/**
 * @ai-summary React Query hooks for dashboard data
 * @ai-context Fetches vehicles, maintenance schedules, and document expiry data
 * to compute per-vehicle health indicators for the fleet roster.
 */

import { useQuery } from '@tanstack/react-query';
import { useAuth0 } from '@auth0/auth0-react';
import { vehiclesApi } from '../../vehicles/api/vehicles.api';
import { maintenanceApi } from '../../maintenance/api/maintenance.api';
import { documentsApi } from '../../documents/api/documents.api';
import { MaintenanceSchedule } from '../../maintenance/types/maintenance.types';
import { DocumentRecord } from '../../documents/types/documents.types';
import { Vehicle } from '../../vehicles/types/vehicles.types';
import { VehicleRosterData } from '../types';
import { computeVehicleHealth } from '../utils/computeVehicleHealth';

export { computeVehicleHealth };

interface DashboardData {
  vehicles: Vehicle[];
  schedulesByVehicle: Map<string, MaintenanceSchedule[]>;
  documentsByVehicle: Map<string, DocumentRecord[]>;
  roster: VehicleRosterData[];
}

/**
 * Unified hook that fetches all dashboard data in a single query.
 * Fetches vehicles, maintenance schedules, and document expiry data.
 */
export const useDashboardData = () => {
  const { isAuthenticated, isLoading: authLoading } = useAuth0();

  return useQuery({
    queryKey: ['dashboard', 'all'],
    queryFn: async (): Promise<DashboardData> => {
      // Fetch vehicles first (need IDs for schedule queries)
      const vehicles = await vehiclesApi.getAll();

      // Fetch maintenance schedules per vehicle in parallel
      const allSchedulesArrays = await Promise.all(
        vehicles.map(v => maintenanceApi.getSchedulesByVehicle(v.id))
      );

      const schedulesByVehicle = new Map<string, MaintenanceSchedule[]>();
      vehicles.forEach((vehicle, index) => {
        schedulesByVehicle.set(vehicle.id, allSchedulesArrays[index]);
      });

      // Fetch document expiry data (insurance + registration) with graceful degradation
      let expiryDocs: DocumentRecord[] = [];
      try {
        const [insuranceDocs, registrationDocs] = await Promise.all([
          documentsApi.list({ type: 'insurance' }),
          documentsApi.list({ type: 'registration' }),
        ]);
        expiryDocs = [...insuranceDocs, ...registrationDocs]
          .filter(d => d.expirationDate != null);
      } catch {
        // Gracefully degrade: dashboard still works with maintenance-only health data
      }

      // Group documents by vehicleId
      const documentsByVehicle = new Map<string, DocumentRecord[]>();
      for (const doc of expiryDocs) {
        const vehicleId = doc.vehicleId;
        if (!documentsByVehicle.has(vehicleId)) {
          documentsByVehicle.set(vehicleId, []);
        }
        documentsByVehicle.get(vehicleId)!.push(doc);
      }

      // Compute roster data per vehicle
      const roster: VehicleRosterData[] = vehicles.map(vehicle => {
        const schedules = schedulesByVehicle.get(vehicle.id) || [];
        const documents = documentsByVehicle.get(vehicle.id) || [];
        const { health, attentionItems } = computeVehicleHealth(schedules, documents);
        return { vehicle, health, attentionItems };
      });

      return { vehicles, schedulesByVehicle, documentsByVehicle, roster };
    },
    enabled: isAuthenticated && !authLoading,
    staleTime: 2 * 60 * 1000,
    gcTime: 5 * 60 * 1000,
    retry: (failureCount, error: unknown) => {
      const status = (error as { response?: { status?: number } })?.response?.status;
      if (status === 401 && failureCount < 3) {
        return true;
      }
      return false;
    },
    retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
  });
};

/**
 * Derived hook returning vehicle roster data for the dashboard grid.
 */
export const useVehicleRoster = () => {
  const { data, isLoading, error, refetch } = useDashboardData();

  return {
    data: data?.roster,
    vehicles: data?.vehicles,
    isLoading,
    error,
    refetch,
  };
};
