'use client';

/**
 * Personal Stats Hook
 * 
 * Track user's delivery statistics
 */

import { useQuery } from '@tanstack/react-query';
import api from '../lib/api-client';

export interface PersonalStats {
  // Today
  todayDeliveries: number;
  todayQuantity: number;
  todaySchools: number;
  
  // This week
  weekDeliveries: number;
  weekQuantity: number;
  weekSchools: number;
  weekTarget: number;
  
  // This month
  monthDeliveries: number;
  monthQuantity: number;
  monthSchools: number;
  monthTarget: number;
  
  // Rates
  completionRate: number;
  avgDeliveriesPerDay: number;
  
  // Streak
  currentStreak: number;
  longestStreak: number;
  
  // Rankings (optional)
  rank?: number;
  totalUsers?: number;
}

export interface DailyBreakdown {
  date: string;
  deliveries: number;
  quantity: number;
  schools: string[];
}

export interface RegionCoverage {
  region: string;
  deliveries: number;
  quantity: number;
  schools: number;
  lat?: number;
  lng?: number;
}

export function usePersonalStats() {
  const { data, isLoading, error, refetch } = useQuery({
    queryKey: ['personal-stats'],
    queryFn: async () => {
      const response = await api.get('/deliveries', {
        params: {
          limit: 1000,
          cache_bust: Date.now(),
        },
      });
      
      const deliveries = response.data?.data || [];
      const now = new Date();
      const today = now.toISOString().split('T')[0];
      const weekStart = new Date(now);
      weekStart.setDate(weekStart.getDate() - weekStart.getDay());
      const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
      
      // Calculate stats
      const todayDeliveries = deliveries.filter((d: any) => d.delivery_date === today);
      const weekDeliveries = deliveries.filter((d: any) => new Date(d.delivery_date) >= weekStart);
      const monthDeliveries = deliveries.filter((d: any) => new Date(d.delivery_date) >= monthStart);
      
      const uniqueSchools = (arr: any[]) => new Set(arr.map(d => d.school_id)).size;
      const sumQuantity = (arr: any[]) => arr.reduce((sum, d) => sum + (parseFloat(d.actual_quantity) || 0), 0);
      
      // Calculate streak
      let currentStreak = 0;
      let longestStreak = 0;
      let tempStreak = 0;
      const sortedDates = [...new Set<string>(deliveries.map((d: any) => String(d.delivery_date)))].sort().reverse();
      
      for (let i = 0; i < sortedDates.length; i++) {
        const date = new Date(sortedDates[i]);
        const expectedDate = new Date(now);
        expectedDate.setDate(expectedDate.getDate() - i);
        
        if (date.toISOString().split('T')[0] === expectedDate.toISOString().split('T')[0]) {
          tempStreak++;
          if (i === 0 || currentStreak > 0) currentStreak = tempStreak;
        } else if (i === 0) {
          // Check if yesterday had a delivery
          const yesterday = new Date(now);
          yesterday.setDate(yesterday.getDate() - 1);
          if (date.toISOString().split('T')[0] === yesterday.toISOString().split('T')[0]) {
            tempStreak = 1;
            currentStreak = 1;
          } else {
            tempStreak = 0;
          }
        } else {
          longestStreak = Math.max(longestStreak, tempStreak);
          tempStreak = 0;
        }
      }
      longestStreak = Math.max(longestStreak, tempStreak);
      
      // Daily breakdown for charts
      const dailyMap = new Map<string, DailyBreakdown>();
      deliveries.forEach((d: any) => {
        const date = d.delivery_date;
        if (!dailyMap.has(date)) {
          dailyMap.set(date, { date, deliveries: 0, quantity: 0, schools: [] });
        }
        const entry = dailyMap.get(date)!;
        entry.deliveries++;
        entry.quantity += parseFloat(d.actual_quantity) || 0;
        if (!entry.schools.includes(d.school_name)) {
          entry.schools.push(d.school_name);
        }
      });
      const dailyBreakdown = Array.from(dailyMap.values()).sort((a, b) => a.date.localeCompare(b.date));
      
      // Region coverage for heat map
      const regionMap = new Map<string, RegionCoverage>();
      deliveries.forEach((d: any) => {
        const region = d.school_region || d.region || 'Unknown';
        if (!regionMap.has(region)) {
          regionMap.set(region, { region, deliveries: 0, quantity: 0, schools: 0 });
        }
        const entry = regionMap.get(region)!;
        entry.deliveries++;
        entry.quantity += parseFloat(d.actual_quantity) || 0;
      });
      // Add unique schools per region
      const schoolsByRegion = new Map<string, Set<number>>();
      deliveries.forEach((d: any) => {
        const region = d.school_region || d.region || 'Unknown';
        if (!schoolsByRegion.has(region)) {
          schoolsByRegion.set(region, new Set());
        }
        schoolsByRegion.get(region)!.add(d.school_id);
      });
      schoolsByRegion.forEach((schools, region) => {
        const entry = regionMap.get(region);
        if (entry) entry.schools = schools.size;
      });
      const regionCoverage = Array.from(regionMap.values()).sort((a, b) => b.deliveries - a.deliveries);
      
      // Working days this month
      const workingDays = Math.ceil((now.getTime() - monthStart.getTime()) / (1000 * 60 * 60 * 24));
      
      const stats: PersonalStats = {
        todayDeliveries: todayDeliveries.length,
        todayQuantity: sumQuantity(todayDeliveries),
        todaySchools: uniqueSchools(todayDeliveries),
        
        weekDeliveries: weekDeliveries.length,
        weekQuantity: sumQuantity(weekDeliveries),
        weekSchools: uniqueSchools(weekDeliveries),
        weekTarget: 35, // Example target
        
        monthDeliveries: monthDeliveries.length,
        monthQuantity: sumQuantity(monthDeliveries),
        monthSchools: uniqueSchools(monthDeliveries),
        monthTarget: 150, // Example target
        
        completionRate: monthDeliveries.length > 0 ? Math.min(100, Math.round((monthDeliveries.length / 150) * 100)) : 0,
        avgDeliveriesPerDay: workingDays > 0 ? Math.round(monthDeliveries.length / workingDays * 10) / 10 : 0,
        
        currentStreak,
        longestStreak,
      };
      
      return {
        stats,
        dailyBreakdown,
        regionCoverage,
        recentDeliveries: deliveries.slice(0, 10),
      };
    },
    staleTime: 60_000,
  });

  return {
    stats: data?.stats || null,
    dailyBreakdown: data?.dailyBreakdown || [],
    regionCoverage: data?.regionCoverage || [],
    recentDeliveries: data?.recentDeliveries || [],
    isLoading,
    error,
    refetch,
  };
}
