/**
 * @ai-summary React Query hooks for dashboard data
 * @ai-context Unified data fetching to prevent duplicate API calls
 */

import { useQuery } from '@tanstack/react-query';
import { useAuth0 } from '@auth0/auth0-react';
import { vehiclesApi } from '../../vehicles/api/vehicles.api';
import { fuelLogsApi } from '../../fuel-logs/api/fuel-logs.api';
import { maintenanceApi } from '../../maintenance/api/maintenance.api';
import { DashboardSummary, VehicleNeedingAttention } from '../types';
import { MaintenanceSchedule } from '../../maintenance/types/maintenance.types';

/**
 * Combined dashboard data structure
 */
interface DashboardData {
  summary: DashboardSummary;
  vehiclesNeedingAttention: VehicleNeedingAttention[];
}

/**
 * Unified hook that fetches all dashboard data in a single query
 * Prevents duplicate API calls for vehicles and maintenance schedules
 */
export const useDashboardData = () => {
  const { isAuthenticated, isLoading: authLoading } = useAuth0();

  return useQuery({
    queryKey: ['dashboard', 'all'],
    queryFn: async (): Promise<DashboardData> => {
      // Fetch vehicles and fuel logs in parallel
      const [vehicles, fuelLogs] = await Promise.all([
        vehiclesApi.getAll(),
        fuelLogsApi.getUserFuelLogs(),
      ]);

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

      // Create a map of vehicle ID to schedules for efficient lookup
      const schedulesByVehicle = new Map<string, MaintenanceSchedule[]>();
      vehicles.forEach((vehicle, index) => {
        schedulesByVehicle.set(vehicle.id, allSchedulesArrays[index]);
      });

      const flatSchedules = allSchedulesArrays.flat();
      const now = new Date();

      // Calculate summary stats
      const thirtyDaysFromNow = new Date();
      thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30);

      const upcomingMaintenance = flatSchedules.filter(schedule => {
        if (!schedule.nextDueDate) return false;
        const dueDate = new Date(schedule.nextDueDate);
        return dueDate >= now && dueDate <= thirtyDaysFromNow;
      });

      const sevenDaysAgo = new Date();
      sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

      const recentFuelLogs = fuelLogs.filter(log => {
        const logDate = new Date(log.dateTime);
        return logDate >= sevenDaysAgo;
      });

      const summary: DashboardSummary = {
        totalVehicles: vehicles.length,
        upcomingMaintenanceCount: upcomingMaintenance.length,
        recentFuelLogsCount: recentFuelLogs.length,
      };

      // Calculate vehicles needing attention (using already-fetched schedules)
      const vehiclesNeedingAttention: VehicleNeedingAttention[] = [];

      for (const vehicle of vehicles) {
        const schedules = schedulesByVehicle.get(vehicle.id) || [];

        const overdueSchedules = schedules.filter(schedule => {
          if (!schedule.nextDueDate) return false;
          const dueDate = new Date(schedule.nextDueDate);
          return dueDate < now;
        });

        if (overdueSchedules.length > 0) {
          const mostOverdue = overdueSchedules.reduce((oldest, current) => {
            const oldestDate = new Date(oldest.nextDueDate!);
            const currentDate = new Date(current.nextDueDate!);
            return currentDate < oldestDate ? current : oldest;
          });

          const daysOverdue = Math.floor(
            (now.getTime() - new Date(mostOverdue.nextDueDate!).getTime()) / (1000 * 60 * 60 * 24)
          );

          let priority: 'high' | 'medium' | 'low' = 'low';
          if (daysOverdue > 30) {
            priority = 'high';
          } else if (daysOverdue > 14) {
            priority = 'medium';
          }

          vehiclesNeedingAttention.push({
            ...vehicle,
            reason: `${overdueSchedules.length} overdue maintenance ${overdueSchedules.length === 1 ? 'item' : 'items'}`,
            priority,
          });
        }
      }

      // Sort by priority (high -> medium -> low)
      const priorityOrder = { high: 0, medium: 1, low: 2 };
      vehiclesNeedingAttention.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);

      return { summary, vehiclesNeedingAttention };
    },
    enabled: isAuthenticated && !authLoading,
    staleTime: 2 * 60 * 1000, // 2 minutes
    gcTime: 5 * 60 * 1000, // 5 minutes cache time
    retry: (failureCount, error: any) => {
      if (error?.response?.status === 401 && failureCount < 3) {
        console.log(`[Mobile Auth] Dashboard retry ${failureCount + 1}/3 for 401 error`);
        return true;
      }
      return false;
    },
    retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
  });
};

/**
 * Hook to fetch dashboard summary stats
 * Derives from unified dashboard data query
 */
export const useDashboardSummary = () => {
  const { data, isLoading, error, refetch } = useDashboardData();

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

/**
 * Hook to fetch vehicles needing attention (overdue maintenance)
 * Derives from unified dashboard data query
 */
export const useVehiclesNeedingAttention = () => {
  const { data, isLoading, error, refetch } = useDashboardData();

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