import { useCallback, useRef, useEffect, useMemo } from 'react';

// Components
import { ClosedRequestsHeader } from './components/ClosedRequestsHeader';
import { ClosedRequestsList } from './components/ClosedRequestsList';
import { ClosedRequestsEmpty } from './components/ClosedRequestsEmpty';
import { ClosedRequestsPagination } from './components/ClosedRequestsPagination';

// Hooks
import { useClosedRequests } from './hooks/useClosedRequests';
import { useClosedRequestsFilters } from './hooks/useClosedRequestsFilters';

// Types
import type { ClosedRequestsProps } from './types/closedRequests.types';

// Utils & Factory
import { getUserFilterType } from '@/utils/userFilterUtils';
import { getClosedRequestsFilters } from '@/flows';
import { TokenManager } from '@/utils/tokenManager';

export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) {
  // Data fetching hook
  const closedRequests = useClosedRequests({ itemsPerPage: 10 });

  // Filters hook - use ref to avoid circular dependency
  const fetchRef = useRef(closedRequests.fetchRequests);
  fetchRef.current = closedRequests.fetchRequests;

  const filters = useClosedRequestsFilters();

  // Get user filter type and corresponding filter component (plug-and-play pattern)
  const userFilterType = useMemo(() => {
    try {
      const userData = TokenManager.getUserData();
      return getUserFilterType(userData);
    } catch (error) {
      console.error('[ClosedRequests] Error getting user filter type:', error);
      return 'STANDARD' as const;
    }
  }, []);

  // Get the appropriate filter component based on user type
  const ClosedRequestsFiltersComponent = useMemo(() => {
    return getClosedRequestsFilters(userFilterType);
  }, [userFilterType]);

  const isDealer = userFilterType === 'DEALER';
  const prevFiltersRef = useRef({
    searchTerm: filters.searchTerm,
    statusFilter: filters.statusFilter,
    priorityFilter: filters.priorityFilter,
    templateTypeFilter: filters.templateTypeFilter,
    sortBy: filters.sortBy,
    sortOrder: filters.sortOrder,
  });
  const hasInitialFetchRun = useRef(false);
  
  // Initial fetch on mount - use stored page from Redux
  useEffect(() => {
    const storedPage = filters.currentPage || 1;
    fetchRef.current(storedPage, {
      search: filters.searchTerm || undefined,
      status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined,
      // Only include priority and templateType filters if user is not a dealer
      priority: !isDealer && filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined,
      templateType: !isDealer && filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined,
      sortBy: filters.sortBy,
      sortOrder: filters.sortOrder,
    });
    hasInitialFetchRun.current = true;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isDealer]); // Re-fetch if dealer status changes
  
  // Track filter changes and refetch
  useEffect(() => {
    if (!hasInitialFetchRun.current) return;
    
    const prev = prevFiltersRef.current;
    const hasChanged = 
      prev.searchTerm !== filters.searchTerm ||
      prev.statusFilter !== filters.statusFilter ||
      prev.priorityFilter !== filters.priorityFilter ||
      prev.templateTypeFilter !== filters.templateTypeFilter ||
      prev.sortBy !== filters.sortBy ||
      prev.sortOrder !== filters.sortOrder;
    
    if (!hasChanged) return; // No actual change, skip
    
    // Debounce search
    const timeoutId = setTimeout(() => {
      filters.setCurrentPage(1); // Reset to page 1 when filters change
      fetchRef.current(1, {
        search: filters.searchTerm || undefined,
        status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined,
        priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined,
        templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined,
        sortBy: filters.sortBy,
        sortOrder: filters.sortOrder,
      });
      
      // Update previous values
      prevFiltersRef.current = {
        searchTerm: filters.searchTerm,
        statusFilter: filters.statusFilter,
        priorityFilter: filters.priorityFilter,
        templateTypeFilter: filters.templateTypeFilter,
        sortBy: filters.sortBy,
        sortOrder: filters.sortOrder,
      };
    }, filters.searchTerm !== prev.searchTerm ? 500 : 0);
    
    return () => clearTimeout(timeoutId);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [filters.searchTerm, filters.statusFilter, filters.priorityFilter, filters.templateTypeFilter, filters.sortBy, filters.sortOrder, isDealer]);

  // Page change handler
  const handlePageChange = useCallback(
    (newPage: number) => {
      if (newPage >= 1 && newPage <= closedRequests.pagination.totalPages) {
        filters.setCurrentPage(newPage); // Update page in Redux
        closedRequests.fetchRequests(newPage, {
          search: filters.searchTerm || undefined,
          status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined,
          priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined,
          templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined,
          sortBy: filters.sortBy,
          sortOrder: filters.sortOrder,
        });
      }
    },
    [closedRequests, filters]
  );

  // Refresh handler
  const handleRefresh = useCallback(() => {
    closedRequests.handleRefresh({
      search: filters.searchTerm || undefined,
      status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined,
      priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined,
      templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined,
      sortBy: filters.sortBy,
      sortOrder: filters.sortOrder,
    });
  }, [closedRequests, filters]);

  return (
    <div className="space-y-4 sm:space-y-6 max-w-7xl mx-auto" data-testid="closed-requests-page">
      {/* Header */}
      <ClosedRequestsHeader
        totalRecords={closedRequests.pagination.totalRecords}
        loading={closedRequests.loading}
        refreshing={closedRequests.refreshing}
        onRefresh={handleRefresh}
      />

      {/* Filters - Plug-and-play pattern */}
      <ClosedRequestsFiltersComponent
        searchTerm={filters.searchTerm}
        priorityFilter={filters.priorityFilter}
        statusFilter={filters.statusFilter}
        templateTypeFilter={filters.templateTypeFilter}
        sortBy={filters.sortBy}
        sortOrder={filters.sortOrder}
        activeFiltersCount={
          isDealer
            ? // For dealers: only count search and status (closure type)
              [filters.searchTerm, filters.statusFilter !== 'all' ? filters.statusFilter : null].filter(Boolean).length
            : // For standard users: count all filters
              filters.activeFiltersCount
        }
        onSearchChange={filters.setSearchTerm}
        onPriorityChange={filters.setPriorityFilter}
        onStatusChange={filters.setStatusFilter}
        onTemplateTypeChange={filters.setTemplateTypeFilter}
        onSortByChange={filters.setSortBy}
        onSortOrderChange={() => filters.setSortOrder(filters.sortOrder === 'asc' ? 'desc' : 'asc')}
        onClearFilters={filters.clearFilters}
      />

      {/* Requests List */}
      <ClosedRequestsList
        requests={closedRequests.requests}
        loading={closedRequests.loading}
        onViewRequest={onViewRequest}
      />

      {/* Empty State */}
      {closedRequests.requests.length === 0 && !closedRequests.loading && (
        <ClosedRequestsEmpty
          searchTerm={filters.searchTerm}
          activeFiltersCount={filters.activeFiltersCount}
          onClearFilters={filters.clearFilters}
        />
      )}

      {/* Pagination */}
      {!closedRequests.loading && (
        <ClosedRequestsPagination
          pagination={closedRequests.pagination}
          onPageChange={handlePageChange}
        />
      )}
    </div>
  );
}

