import { useCallback, useRef, useState, useEffect, useMemo } from 'react';
import { FileText } from 'lucide-react';
import { PageHeader } from '@/components/common/PageHeader';
import { Pagination } from '@/components/common/Pagination';
import dashboardService from '@/services/dashboard.service';
import { useAuth } from '@/contexts/AuthContext';

// Components
import { MyRequestsStatsSection } from './components/MyRequestsStats';
import { MyRequestsFilters as MyRequestsFiltersComponent } from './components/MyRequestsFilters';
import { MyRequestsList } from './components/MyRequestsList';

// Hooks
import { useMyRequests } from './hooks/useMyRequests';
import { useMyRequestsFilters } from './hooks/useMyRequestsFilters';

// Utils
import { transformRequests } from './utils/requestTransformers';

interface MyRequestsProps {
  onViewRequest: (requestId: string, requestTitle?: string, status?: string) => void;
  dynamicRequests?: any[];
}

export function MyRequests({ onViewRequest, dynamicRequests = [] }: MyRequestsProps) {
  const { user } = useAuth();
  
  // Data fetching hook
  const myRequests = useMyRequests({ itemsPerPage: 10 });

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

  const filters = useMyRequestsFilters();
  const prevFiltersRef = useRef({
    searchTerm: filters.searchTerm,
    statusFilter: filters.statusFilter,
    priorityFilter: filters.priorityFilter,
    templateTypeFilter: filters.templateTypeFilter,
  });
  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,
      priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined,
      templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined,
    });
    hasInitialFetchRun.current = true;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []); // Only on mount
  
  // 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;
    
    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,
        });
      
      // Update previous values
      prevFiltersRef.current = {
        searchTerm: filters.searchTerm,
        statusFilter: filters.statusFilter,
        priorityFilter: filters.priorityFilter,
        templateTypeFilter: filters.templateTypeFilter,
      };
    }, 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]);

  // State for backend stats (calculated from entire dataset via SQL queries)
  const [backendStats, setBackendStats] = useState<{
    total: number;
    pending: number;
    paused: number;
    approved: number;
    rejected: number;
    draft: number;
    closed: number;
  } | null>(null);
  const [loadingStats, setLoadingStats] = useState(false);

  // Fetch stats from backend API (calculates from entire dataset using SQL, not by fetching data)
  // Stats should reflect filters (priority, search) but NOT status
  // Status filter should not affect stats - stats should always show all status counts
  // Total changes when other filters are applied, but stays stable when only status changes
  const fetchBackendStats = useCallback(async () => {
    if (!user?.userId) return;

    try {
      setLoadingStats(true);
      
      // Use backend stats API - explicitly filter by user's initiator_id
      // This ensures "My Requests" only shows requests where user is the initiator
      // Even for admin users, we want to see only their own requests in "My Requests"
      // This calculates stats from entire dataset using SQL COUNT queries, not by fetching data
      // Note: status is undefined - stats should show all statuses, not filtered by status
      // Note: dateRange is 'all' - stats should match the list which shows all requests
      const stats = await dashboardService.getRequestStats(
        'all', // dateRange - 'all' means no date filter to match the list
        undefined, // startDate
        undefined, // endDate
        undefined, // status - My Requests stats show all statuses, not filtered by status (same as All Requests)
        filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined,
        filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, // templateType
        undefined, // department
        user.userId, // initiator - explicitly filter by user's own userId to ensure only their requests
        undefined, // approver
        undefined, // approverType
        filters.searchTerm || undefined,
        undefined, // slaCompliance
        true // viewAsUser - treat as normal user even if admin
      );

      setBackendStats({
        total: stats.totalRequests || 0,
        pending: stats.openRequests || 0,
        paused: stats.pausedRequests || 0,
        approved: stats.approvedRequests || 0,
        rejected: stats.rejectedRequests || 0,
        draft: stats.draftRequests || 0,
        closed: stats.closedRequests || 0,
      });
    } catch (error) {
      console.error('Failed to fetch backend stats:', error);
      setBackendStats(null);
    } finally {
      setLoadingStats(false);
    }
  }, [user?.userId, filters.searchTerm, filters.priorityFilter, filters.templateTypeFilter]); // Exclude statusFilter - stats don't change when only status changes

  // Fetch stats when filters change (excluding status filter)
  // Stats should reflect priority and search filters, but NOT status filter
  // Total changes when other filters are applied, but stays stable when only status changes
  useEffect(() => {
    const timeoutId = setTimeout(() => {
      fetchBackendStats();
    }, filters.searchTerm ? 500 : 0);

    return () => clearTimeout(timeoutId);
  }, [filters.searchTerm, filters.priorityFilter, filters.templateTypeFilter, fetchBackendStats]); // Exclude statusFilter - stats don't change when only status changes

  // Handle dynamic requests (fallback until API loads)
  const convertedDynamicRequests = transformRequests(dynamicRequests);
  const sourceRequests = myRequests.hasFetchedFromApi ? myRequests.requests : convertedDynamicRequests;

  // Calculate stats from backend stats API (calculated from entire dataset via SQL queries)
  // This is much more efficient - backend uses COUNT queries, no data fetching needed
  const stats = useMemo(() => {
    if (backendStats) {
      // Use backend stats (calculated from entire dataset via SQL COUNT queries)
      return {
        total: backendStats.total || 0,
        pending: backendStats.pending || 0,
        paused: backendStats.paused || 0,
        approved: backendStats.approved || 0,
        rejected: backendStats.rejected || 0,
        draft: backendStats.draft || 0,
        closed: backendStats.closed || 0,
      };
    }
    
    // Fallback: if stats haven't loaded yet, show zeros
    return {
      total: 0,
      pending: 0,
      paused: 0,
      approved: 0,
      rejected: 0,
      draft: 0,
      closed: 0,
    };
  }, [backendStats]);

  // Page change handler
  const handlePageChange = useCallback(
    (newPage: number) => {
      if (newPage >= 1 && newPage <= myRequests.pagination.totalPages) {
        filters.setCurrentPage(newPage); // Update page in Redux
        myRequests.fetchMyRequests(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,
        });
      }
    },
    [myRequests, filters]
  );

  return (
    <div className="space-y-4 sm:space-y-6 max-w-7xl mx-auto" data-testid="my-requests-page">
      {/* Page Header */}
      <PageHeader
        icon={FileText}
        title="My Requests"
        description="Track and manage all your submitted requests"
        badge={{
          value: `${stats.total} total`,
          label: 'requests',
          loading: myRequests.loading || loadingStats,
        }}
        testId="my-requests-header"
      />

      {/* Stats Overview */}
      <MyRequestsStatsSection 
        stats={stats} 
        onStatusFilter={(status) => {
          filters.setStatusFilter(status);
        }}
      />

      {/* Filters and Search */}
      <MyRequestsFiltersComponent
        searchTerm={filters.searchTerm}
        statusFilter={filters.statusFilter}
        priorityFilter={filters.priorityFilter}
        templateTypeFilter={filters.templateTypeFilter}
        onSearchChange={filters.setSearchTerm}
        onStatusChange={filters.setStatusFilter}
        onPriorityChange={filters.setPriorityFilter}
        onTemplateTypeChange={filters.setTemplateTypeFilter}
      />

      {/* Requests List */}
      <MyRequestsList
        requests={sourceRequests}
        loading={myRequests.loading}
        searchTerm={filters.searchTerm}
        statusFilter={filters.statusFilter}
        priorityFilter={filters.priorityFilter}
        onViewRequest={onViewRequest}
      />

      {/* Pagination */}
      <Pagination
        currentPage={filters.currentPage || myRequests.pagination.currentPage}
        totalPages={myRequests.pagination.totalPages}
        totalRecords={myRequests.pagination.totalRecords}
        itemsPerPage={myRequests.pagination.itemsPerPage}
        onPageChange={handlePageChange}
        loading={myRequests.loading}
        itemLabel="requests"
        testIdPrefix="my-requests-pagination"
      />
    </div>
  );
}
