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 toApiFilters = useCallback(() => {
    const f = filters.getFilters();
    return {
      search: f.search || undefined,
      status: f.status !== 'all' ? f.status : undefined,
      priority: !isDealer && f.priority ? f.priority : undefined,
      templateType: f.templateType,
      financialYear: f.financialYear,
      quarter: f.quarter,
      sortBy: f.sortBy,
      sortOrder: f.sortOrder,
    };
  }, [filters, isDealer]);

  const prevFiltersRef = useRef({
    searchTerm: filters.searchTerm,
    statusFilter: filters.statusFilter,
    priorityFilter: filters.priorityFilter,
    templateTypeFilter: filters.templateTypeFilter,
    form16FinancialYear: filters.form16FinancialYear,
    form16Quarter: filters.form16Quarter,
    sortBy: filters.sortBy,
    sortOrder: filters.sortOrder,
  });
  const hasInitialFetchRun = useRef(false);

  useEffect(() => {
    const storedPage = filters.currentPage || 1;
    fetchRef.current(storedPage, toApiFilters());
    hasInitialFetchRun.current = true;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isDealer]);

  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.form16FinancialYear !== filters.form16FinancialYear ||
      prev.form16Quarter !== filters.form16Quarter ||
      prev.sortBy !== filters.sortBy ||
      prev.sortOrder !== filters.sortOrder;
    if (!hasChanged) return;
    const timeoutId = setTimeout(() => {
      filters.setCurrentPage(1);
      fetchRef.current(1, toApiFilters());
      prevFiltersRef.current = {
        searchTerm: filters.searchTerm,
        statusFilter: filters.statusFilter,
        priorityFilter: filters.priorityFilter,
        templateTypeFilter: filters.templateTypeFilter,
        form16FinancialYear: filters.form16FinancialYear,
        form16Quarter: filters.form16Quarter,
        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.form16FinancialYear, filters.form16Quarter, filters.sortBy, filters.sortOrder, isDealer]);

  const handlePageChange = useCallback(
    (newPage: number) => {
      if (newPage >= 1 && newPage <= closedRequests.pagination.totalPages) {
        filters.setCurrentPage(newPage);
        closedRequests.fetchRequests(newPage, toApiFilters());
      }
    },
    [closedRequests, filters, toApiFilters]
  );

  const handleRefresh = useCallback(() => {
    closedRequests.handleRefresh(toApiFilters());
  }, [closedRequests, toApiFilters]);

  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}
        form16FinancialYear={filters.form16FinancialYear}
        form16Quarter={filters.form16Quarter}
        sortBy={filters.sortBy}
        sortOrder={filters.sortOrder}
        activeFiltersCount={filters.activeFiltersCount}
        onSearchChange={filters.setSearchTerm}
        onPriorityChange={filters.setPriorityFilter}
        onStatusChange={filters.setStatusFilter}
        onTemplateTypeChange={filters.setTemplateTypeFilter}
        onForm16FinancialYearChange={filters.setForm16FinancialYear}
        onForm16QuarterChange={filters.setForm16Quarter}
        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>
  );
}

