import { useEffect, useMemo, useRef, useCallback, useState } from "react";
import { useTableManager, TableConfig } from "@/hooks/use-table-manager";
import { useDriverAbsenceStore, DriverAbsenceList, Search } from "@/shared/api/stores/driverAbsenceStore";
import { IDriverAbsence } from "@/shared/types/driver-absence";
import { DEFAULT_ABSENCE_DRIVER_TABLE_HEAD } from "@/shared/_mock/_absenceDriver";
import { BinaryQuestion } from "@/shared/types/trajet";

const map = (a: DriverAbsenceList): IDriverAbsence => ({
  id: a.id.toString(),
  driverName: a.driverName,
  chauffeur: a.driverName,
  typeAbsence: a.absenceType,
  dateDebut: a.startDate,
  dateFin: a.endDate,
  chauffeurAffecte: a.isAssigned ? BinaryQuestion.Oui : BinaryQuestion.Non,
  modeReception: a.receptionMode,
  nombreHeures: a.nbHours?.toString() ?? "",
  autorisePar: a.authorizedByName ?? a.authorizedBy?.toString() ?? "",
  validePar: a.validatedByName ?? a.validatedBy?.toString() ?? "",
  validatedByName: a.validatedByName ?? null,
  authorizedByName: a.authorizedByName ?? null,
  statut: a.status,
  justificatif: new File([], a.supportingDocumentId?.toString() ?? ''),
  supportingDocumentId: a.supportingDocumentId,
  driver: a.driver?.id ? a.driver : undefined
});

function cleanFilters(filters: Record<string, any>) {
  const cleaned: Record<string, any> = {};
  Object.keys(filters).forEach((key) => {
    const value = filters[key];
    if (
      value !== undefined &&
      value !== null &&
      value !== ""
    ) {
      cleaned[key] = value;
    }
  });
  return cleaned;
}

// Map frontend field names to backend field names for sorting
function mapSortFieldToBackend(field: string): string {
  const fieldMapping: Record<string, string> = {
    'typeAbsence': 'absenceType',
    'dateDebut': 'startDate',
    'dateFin': 'endDate',
    'chauffeurAffecte': 'isAssigned',
    'modeReception': 'receptionMode',
    'nombreHeures': 'nbHours',
    'autorisePar': 'authorizedByName',
    'validePar': 'validatedByName',
    'statut': 'status',
    'chauffeur': 'driverName',
    'driverName': 'driverName'
  };
  
  return fieldMapping[field] || field;
}

export function useTreatedAbsenceDriverTable(filters: Search, refreshKey: number) {
  const { processed, processedTotal, fetchProcessed, processedLoading } = useDriverAbsenceStore();
  const lastQueryRef = useRef<string>("");
  const debounceTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  
  // Local state for sorting and pagination
  const [localSortField, setLocalSortField] = useState<string>('id');
  const [localSortDirection, setLocalSortDirection] = useState<string>('asc');
  const [localPage, setLocalPage] = useState<number>(0);
  const [localPageSize, setLocalPageSize] = useState<number>(20);

  const rows = useMemo(() => processed.map(map), [processed]);

  const config: TableConfig<IDriverAbsence> = {
    initialData: rows,
    defaultTableHead: DEFAULT_ABSENCE_DRIVER_TABLE_HEAD(false),
  };

  const tableManager = useTableManager<IDriverAbsence>(config);

  // Override the table onSort function to handle server-side sorting
  const customTable = {
    ...tableManager.table,
    onSort: useCallback((id: string) => {
      const isAsc = localSortField === id && localSortDirection === 'asc';
      const newDirection = isAsc ? 'desc' : 'asc';
      
      setLocalSortField(id);
      setLocalSortDirection(newDirection);
      setLocalPage(0); // Reset to first page when sorting
      
      // Update the local table state for UI consistency
      tableManager.table.onSort(id);
    }, [localSortField, localSortDirection, tableManager.table])
  };

  useEffect(() => {
    // Clear any existing timeout
    if (debounceTimeoutRef.current) {
      clearTimeout(debounceTimeoutRef.current);
    }

    const baseParams = cleanFilters(filters);
    
    // Use local sorting and pagination state
    const sortParams = {
      sortField: mapSortFieldToBackend(localSortField),
      sortDirection: localSortDirection
    };

    const paginationParams = {
      page: localPage,
      size: localPageSize
    };

    // Combine all parameters
    const params = {
      ...baseParams,
      ...sortParams,
      ...paginationParams
    };

    const queryKey = JSON.stringify(params);
    if (lastQueryRef.current === queryKey) return;

    // Check if we need to debounce based on specific fields
    const needsDebounce = baseParams.startDateFrom || baseParams.startDateTo || 
                         baseParams.driverName || baseParams.authorizedByName;

    const executeFetch = () => {
      lastQueryRef.current = queryKey;
      fetchProcessed(params);
    };

    if (needsDebounce) {
      // Debounce for 500ms for text input fields
      debounceTimeoutRef.current = setTimeout(executeFetch, 500);
    } else {
      // Execute immediately for other fields (selects, pagination, sorting)
      executeFetch();
    }

    // Cleanup function
    return () => {
      if (debounceTimeoutRef.current) {
        clearTimeout(debounceTimeoutRef.current);
      }
    };
  }, [fetchProcessed, filters, refreshKey, localSortField, localSortDirection, localPage, localPageSize]);

  // Handle page changes
  const handlePageChange = useCallback((event: React.MouseEvent<HTMLButtonElement> | null, newPage: number) => {
    setLocalPage(newPage);
    tableManager.table.onChangePage(event, newPage);
  }, [tableManager.table]);

  // Handle rows per page changes
  const handleRowsPerPageChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
    const newSize = parseInt(event.target.value, 10);
    if (!isNaN(newSize) && newSize > 0) {
      setLocalPageSize(newSize);
      setLocalPage(0); // Reset to first page when changing page size
    }
    tableManager.table.onChangeRowsPerPage(event);
  }, [tableManager.table]);

  // Handle sorting
  const handleSort = useCallback((sortBy: string, sortDirection: string) => {
    setLocalSortField(sortBy);
    setLocalSortDirection(sortDirection);
    setLocalPage(0);
  }, []);

  return { 
    ...tableManager, 
    table: customTable,
    rows, 
    loading: processedLoading, 
    total: processedTotal,
    onPageChange: handlePageChange,
    onRowsPerPageChange: handleRowsPerPageChange,
    handleSort,
    sortBy: localSortField,
    sortDirection: localSortDirection
  };
}
