import { useState } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { format, startOfWeek, addWeeks } from "date-fns";
import { it } from "date-fns/locale";
import { useLocation } from "wouter";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ChevronLeft, ChevronRight, Calendar, MapPin, Users, AlertTriangle, Car, Edit, CheckCircle2, Plus } from "lucide-react";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { queryClient, apiRequest } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";
import type { GuardAvailability } from "@shared/schema";

interface GuardWithHours {
  guardId: string;
  guardName: string;
  badgeNumber: string;
  hours: number;
}

interface Vehicle {
  vehicleId: string;
  licensePlate: string;
  brand: string;
  model: string;
}

interface SiteData {
  siteId: string;
  siteName: string;
  serviceType: string;
  minGuards: number;
  guards: GuardWithHours[];
  vehicles: Vehicle[];
  totalShiftHours: number;
  guardsAssigned: number;
  missingGuards: number;
  shiftsCount: number;
}

interface DayData {
  date: string;
  dayOfWeek: string;
  sites: SiteData[];
}

interface GeneralPlanningResponse {
  weekStart: string;
  weekEnd: string;
  location: string;
  days: DayData[];
  summary: {
    totalGuardsNeeded: number;
    totalGuardsAssigned: number;
    totalGuardsMissing: number;
  };
}

export default function GeneralPlanning() {
  const [, navigate] = useLocation();
  const { toast } = useToast();
  const [selectedLocation, setSelectedLocation] = useState<string>("roccapiemonte");
  const [weekStart, setWeekStart] = useState<Date>(() => startOfWeek(new Date(), { weekStartsOn: 1 }));
  const [selectedCell, setSelectedCell] = useState<{ siteId: string; siteName: string; date: string; data: SiteData } | null>(null);
  
  // Form state per creazione turno
  const [selectedGuardId, setSelectedGuardId] = useState<string>("");
  const [days, setDays] = useState<number>(1);

  // Query per dati planning settimanale
  const { data: planningData, isLoading } = useQuery<GeneralPlanningResponse>({
    queryKey: ["/api/general-planning", format(weekStart, "yyyy-MM-dd"), selectedLocation],
    queryFn: async () => {
      const response = await fetch(
        `/api/general-planning?weekStart=${format(weekStart, "yyyy-MM-dd")}&location=${selectedLocation}`
      );
      if (!response.ok) throw new Error("Failed to fetch general planning");
      return response.json();
    },
  });

  // Query per guardie disponibili (solo quando dialog è aperto)
  const { data: availableGuards, isLoading: isLoadingGuards } = useQuery<GuardAvailability[]>({
    queryKey: ["/api/guards/availability", format(weekStart, "yyyy-MM-dd"), selectedCell?.siteId, selectedLocation],
    queryFn: async () => {
      if (!selectedCell) return [];
      const response = await fetch(
        `/api/guards/availability?weekStart=${format(weekStart, "yyyy-MM-dd")}&siteId=${selectedCell.siteId}&location=${selectedLocation}`
      );
      if (!response.ok) throw new Error("Failed to fetch guards availability");
      return response.json();
    },
    enabled: !!selectedCell, // Query attiva solo se dialog è aperto
  });

  // Mutation per creare turno multi-giorno
  const createShiftMutation = useMutation({
    mutationFn: async (data: { siteId: string; startDate: string; days: number; guardId: string }) => {
      return apiRequest("POST", "/api/general-planning/shifts", data);
    },
    onSuccess: () => {
      // Invalida cache planning generale
      queryClient.invalidateQueries({ queryKey: ["/api/general-planning"] });
      queryClient.invalidateQueries({ queryKey: ["/api/guards/availability"] });
      
      toast({
        title: "Turno creato",
        description: "Il turno è stato creato con successo",
      });
      
      // Reset form e chiudi dialog
      setSelectedGuardId("");
      setDays(1);
      setSelectedCell(null);
    },
    onError: (error: any) => {
      toast({
        title: "Errore",
        description: error.message || "Impossibile creare il turno",
        variant: "destructive",
      });
    },
  });

  // Handler per submit form creazione turno
  const handleCreateShift = () => {
    if (!selectedCell || !selectedGuardId) return;
    
    createShiftMutation.mutate({
      siteId: selectedCell.siteId,
      startDate: selectedCell.date,
      days,
      guardId: selectedGuardId,
    });
  };

  // Navigazione settimana
  const goToPreviousWeek = () => setWeekStart(addWeeks(weekStart, -1));
  const goToNextWeek = () => setWeekStart(addWeeks(weekStart, 1));
  const goToCurrentWeek = () => setWeekStart(startOfWeek(new Date(), { weekStartsOn: 1 }));

  // Formatta nome sede
  const formatLocation = (loc: string) => {
    const locations: Record<string, string> = {
      roccapiemonte: "Roccapiemonte",
      milano: "Milano",
      roma: "Roma",
    };
    return locations[loc] || loc;
  };

  // Raggruppa siti unici da tutti i giorni
  const allSites = planningData?.days.flatMap(day => day.sites) || [];
  const uniqueSites = Array.from(
    new Map(allSites.map(site => [site.siteId, site])).values()
  );

  // Handler per aprire dialog cella
  const handleCellClick = (siteId: string, siteName: string, date: string, data: SiteData) => {
    setSelectedCell({ siteId, siteName, date, data });
  };

  // Naviga a pianificazione operativa con parametri
  const navigateToOperationalPlanning = () => {
    if (selectedCell) {
      // Encode parameters nella URL
      navigate(`/operational-planning?date=${selectedCell.date}&location=${selectedLocation}`);
    }
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
        <div>
          <h1 className="text-3xl font-bold tracking-tight" data-testid="text-page-title">
            Planning Generale
          </h1>
          <p className="text-muted-foreground">
            Vista settimanale turni con calcolo automatico guardie mancanti
          </p>
        </div>
      </div>

      {/* Filtri e navigazione */}
      <Card>
        <CardContent className="pt-6">
          <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
            {/* Selezione Sede */}
            <div className="flex items-center gap-2">
              <MapPin className="h-4 w-4 text-muted-foreground" />
              <Select value={selectedLocation} onValueChange={setSelectedLocation}>
                <SelectTrigger className="w-[200px]" data-testid="select-location">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="roccapiemonte">Roccapiemonte</SelectItem>
                  <SelectItem value="milano">Milano</SelectItem>
                  <SelectItem value="roma">Roma</SelectItem>
                </SelectContent>
              </Select>
            </div>

            {/* Navigazione settimana */}
            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                size="icon"
                onClick={goToPreviousWeek}
                data-testid="button-previous-week"
              >
                <ChevronLeft className="h-4 w-4" />
              </Button>
              
              <Button
                variant="outline"
                onClick={goToCurrentWeek}
                data-testid="button-current-week"
              >
                <Calendar className="h-4 w-4 mr-2" />
                Settimana Corrente
              </Button>
              
              <Button
                variant="outline"
                size="icon"
                onClick={goToNextWeek}
                data-testid="button-next-week"
              >
                <ChevronRight className="h-4 w-4" />
              </Button>
            </div>

            {/* Info settimana */}
            {planningData && (
              <div className="text-sm text-muted-foreground">
                {format(new Date(planningData.weekStart), "dd MMM", { locale: it })} -{" "}
                {format(new Date(planningData.weekEnd), "dd MMM yyyy", { locale: it })}
              </div>
            )}
          </div>
        </CardContent>
      </Card>

      {/* Summary Guardie Settimana */}
      {!isLoading && planningData?.summary && (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Users className="h-5 w-5" />
              Riepilogo Guardie Settimana
            </CardTitle>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-3 gap-4">
              <div className="text-center p-4 bg-primary/10 rounded-lg border border-primary/20">
                <p className="text-sm text-muted-foreground mb-2">Guardie Necessarie</p>
                <p className="text-4xl font-bold text-primary">{planningData.summary.totalGuardsNeeded}</p>
              </div>
              <div className="text-center p-4 bg-green-500/10 rounded-lg border border-green-500/20">
                <p className="text-sm text-muted-foreground mb-2">Guardie Pianificate</p>
                <p className="text-4xl font-bold text-green-600 dark:text-green-500">{planningData.summary.totalGuardsAssigned}</p>
              </div>
              <div className={`text-center p-4 rounded-lg border ${planningData.summary.totalGuardsMissing > 0 ? 'bg-destructive/10 border-destructive/20' : 'bg-green-500/10 border-green-500/20'}`}>
                <p className="text-sm text-muted-foreground mb-2">Guardie Mancanti</p>
                <p className={`text-4xl font-bold ${planningData.summary.totalGuardsMissing > 0 ? 'text-destructive' : 'text-green-600 dark:text-green-500'}`}>
                  {planningData.summary.totalGuardsMissing}
                </p>
              </div>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Tabella Planning */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Calendar className="h-5 w-5" />
            Planning Settimanale - {formatLocation(selectedLocation)}
          </CardTitle>
        </CardHeader>
        <CardContent>
          {isLoading ? (
            <div className="space-y-4">
              <Skeleton className="h-12 w-full" />
              <Skeleton className="h-32 w-full" />
              <Skeleton className="h-32 w-full" />
            </div>
          ) : planningData ? (
            <div className="overflow-x-auto">
              <table className="w-full border-collapse">
                <thead>
                  <tr className="border-b">
                    <th className="sticky left-0 bg-background p-3 text-left font-semibold min-w-[200px] border-r">
                      Sito
                    </th>
                    {planningData.days.map((day) => (
                      <th
                        key={day.date}
                        className="p-3 text-center font-semibold min-w-[200px] border-r"
                      >
                        <div className="flex flex-col">
                          <span className="text-sm capitalize">
                            {format(new Date(day.date), "EEEE", { locale: it })}
                          </span>
                          <span className="text-xs text-muted-foreground">
                            {format(new Date(day.date), "dd/MM", { locale: it })}
                          </span>
                        </div>
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {uniqueSites.map((site) => (
                    <tr key={site.siteId} className="border-b hover-elevate">
                      <td className="sticky left-0 bg-background p-3 border-r font-medium">
                        <div className="flex flex-col gap-1">
                          <span className="text-sm">{site.siteName}</span>
                          <Badge variant="outline" className="text-xs w-fit">
                            {site.serviceType}
                          </Badge>
                        </div>
                      </td>
                      {planningData.days.map((day) => {
                        const daySiteData = day.sites.find((s) => s.siteId === site.siteId);
                        
                        return (
                          <td
                            key={day.date}
                            className="p-2 border-r hover:bg-accent/5 cursor-pointer"
                            data-testid={`cell-${site.siteId}-${day.date}`}
                            onClick={() => daySiteData && handleCellClick(site.siteId, site.siteName, day.date, daySiteData)}
                          >
                            {daySiteData ? (
                              <div className="space-y-2 text-xs">
                                {/* Riepilogo guardie necessarie/assegnate/mancanti - SEMPRE VISIBILE */}
                                <div className="pb-2 border-b">
                                  {daySiteData.missingGuards > 0 ? (
                                    <Badge variant="destructive" className="w-full justify-center gap-1">
                                      <AlertTriangle className="h-3 w-3" />
                                      Mancano {daySiteData.missingGuards} {daySiteData.missingGuards === 1 ? "guardia" : "guardie"}
                                    </Badge>
                                  ) : (
                                    <Badge variant="default" className="w-full justify-center gap-1 bg-green-600 hover:bg-green-700">
                                      <CheckCircle2 className="h-3 w-3" />
                                      Copertura Completa
                                    </Badge>
                                  )}
                                  <div className="text-xs text-muted-foreground mt-1 text-center">
                                    {daySiteData.guardsAssigned + daySiteData.missingGuards} necessarie · {daySiteData.guardsAssigned} assegnate
                                  </div>
                                </div>

                                {/* Guardie assegnate */}
                                {daySiteData.guards.length > 0 && (
                                  <div className="space-y-1">
                                    <div className="flex items-center gap-1 text-muted-foreground mb-1">
                                      <Users className="h-3 w-3" />
                                      <span className="font-medium">Guardie:</span>
                                    </div>
                                    {daySiteData.guards.map((guard, idx) => (
                                      <div key={idx} className="flex items-center justify-between gap-1 pl-4">
                                        <span className="truncate">{guard.badgeNumber}</span>
                                        <Badge variant="secondary" className="text-xs">
                                          {guard.hours}h
                                        </Badge>
                                      </div>
                                    ))}
                                  </div>
                                )}

                                {/* Veicoli */}
                                {daySiteData.vehicles.length > 0 && (
                                  <div className="space-y-1">
                                    <div className="flex items-center gap-1 text-muted-foreground mb-1">
                                      <Car className="h-3 w-3" />
                                      <span className="font-medium">Veicoli:</span>
                                    </div>
                                    {daySiteData.vehicles.map((vehicle, idx) => (
                                      <div key={idx} className="pl-4 truncate">
                                        {vehicle.licensePlate}
                                      </div>
                                    ))}
                                  </div>
                                )}

                                {/* Info copertura - mostra solo se ci sono turni */}
                                {daySiteData.shiftsCount > 0 && (
                                  <div className="text-xs text-muted-foreground pt-1 border-t">
                                    <div>Turni: {daySiteData.shiftsCount}</div>
                                    <div>Tot. ore: {daySiteData.totalShiftHours}h</div>
                                  </div>
                                )}
                              </div>
                            ) : (
                              <div className="flex items-center justify-center h-full text-muted-foreground">
                                <span className="text-xs">-</span>
                              </div>
                            )}
                          </td>
                        );
                      })}
                    </tr>
                  ))}
                </tbody>
              </table>

              {uniqueSites.length === 0 && (
                <div className="text-center py-12 text-muted-foreground">
                  <Calendar className="h-12 w-12 mx-auto mb-4 opacity-50" />
                  <p>Nessun sito attivo per la sede selezionata</p>
                </div>
              )}
            </div>
          ) : (
            <div className="text-center py-12 text-muted-foreground">
              <p>Errore nel caricamento dei dati</p>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Dialog dettagli cella */}
      <Dialog open={!!selectedCell} onOpenChange={() => setSelectedCell(null)}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <Calendar className="h-5 w-5" />
              {selectedCell?.siteName}
            </DialogTitle>
            <DialogDescription>
              {selectedCell && format(new Date(selectedCell.date), "EEEE dd MMMM yyyy", { locale: it })}
            </DialogDescription>
          </DialogHeader>

          {selectedCell && (
            <div className="space-y-4">
              {/* Info turni */}
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <p className="text-sm text-muted-foreground">Turni Pianificati</p>
                  <p className="text-2xl font-bold">{selectedCell.data.shiftsCount}</p>
                </div>
                <div>
                  <p className="text-sm text-muted-foreground">Ore Totali</p>
                  <p className="text-2xl font-bold">{selectedCell.data.totalShiftHours}h</p>
                </div>
              </div>

              {/* Guardie assegnate */}
              {selectedCell.data.guards.length > 0 && (
                <div className="space-y-2">
                  <div className="flex items-center gap-2 text-sm font-semibold">
                    <Users className="h-4 w-4" />
                    Guardie Assegnate ({selectedCell.data.guards.length})
                  </div>
                  <div className="grid gap-2">
                    {selectedCell.data.guards.map((guard, idx) => (
                      <div key={idx} className="flex items-center justify-between p-2 bg-accent/10 rounded-md">
                        <div>
                          <p className="font-medium">{guard.guardName}</p>
                          <p className="text-xs text-muted-foreground">{guard.badgeNumber}</p>
                        </div>
                        <Badge variant="secondary">{guard.hours}h</Badge>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Veicoli */}
              {selectedCell.data.vehicles.length > 0 && (
                <div className="space-y-2">
                  <div className="flex items-center gap-2 text-sm font-semibold">
                    <Car className="h-4 w-4" />
                    Veicoli Assegnati ({selectedCell.data.vehicles.length})
                  </div>
                  <div className="grid gap-2">
                    {selectedCell.data.vehicles.map((vehicle, idx) => (
                      <div key={idx} className="flex items-center gap-2 p-2 bg-accent/10 rounded-md">
                        <p className="font-medium">{vehicle.licensePlate}</p>
                        <p className="text-sm text-muted-foreground">
                          {vehicle.brand} {vehicle.model}
                        </p>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Guardie mancanti */}
              {selectedCell.data.missingGuards > 0 && (
                <div className="p-4 bg-destructive/10 border border-destructive/20 rounded-md">
                  <div className="flex items-center gap-2 text-destructive font-semibold mb-2">
                    <AlertTriangle className="h-5 w-5" />
                    Attenzione: Guardie Mancanti
                  </div>
                  <p className="text-sm">
                    Servono ancora <span className="font-bold">{selectedCell.data.missingGuards}</span>{" "}
                    {selectedCell.data.missingGuards === 1 ? "guardia" : "guardie"} per coprire completamente il servizio
                    (calcolato su {selectedCell.data.totalShiftHours}h con max 9h per guardia e {selectedCell.data.minGuards} {selectedCell.data.minGuards === 1 ? "guardia minima" : "guardie minime"} contemporanee)
                  </p>
                </div>
              )}

              {/* No turni */}
              {selectedCell.data.shiftsCount === 0 && (
                <div className="text-center py-8 text-muted-foreground">
                  <Calendar className="h-12 w-12 mx-auto mb-4 opacity-50" />
                  <p>Nessun turno pianificato per questa data</p>
                </div>
              )}

              {/* Form creazione nuovo turno */}
              <div className="border-t pt-4 space-y-4">
                <div className="flex items-center gap-2 text-sm font-semibold">
                  <Plus className="h-4 w-4" />
                  Crea Nuovo Turno
                </div>

                <div className="grid gap-4">
                  {/* Select guardia disponibile */}
                  <div className="space-y-2">
                    <Label htmlFor="guard-select">Guardia Disponibile</Label>
                    {isLoadingGuards ? (
                      <Skeleton className="h-10 w-full" />
                    ) : (
                      <Select 
                        value={selectedGuardId} 
                        onValueChange={setSelectedGuardId}
                        disabled={createShiftMutation.isPending}
                      >
                        <SelectTrigger id="guard-select" data-testid="select-guard">
                          <SelectValue placeholder="Seleziona guardia..." />
                        </SelectTrigger>
                        <SelectContent>
                          {availableGuards && availableGuards.length > 0 ? (
                            availableGuards.map((guard) => (
                              <SelectItem key={guard.guardId} value={guard.guardId}>
                                {guard.guardName} ({guard.badgeNumber}) - {guard.weeklyHoursRemaining}h disponibili
                              </SelectItem>
                            ))
                          ) : (
                            <SelectItem value="no-guards" disabled>
                              Nessuna guardia disponibile
                            </SelectItem>
                          )}
                        </SelectContent>
                      </Select>
                    )}
                    {availableGuards && availableGuards.length > 0 && selectedGuardId && (
                      <p className="text-xs text-muted-foreground">
                        {(() => {
                          const guard = availableGuards.find(g => g.guardId === selectedGuardId);
                          return guard ? `Ore assegnate: ${guard.weeklyHoursAssigned}h / ${guard.weeklyHoursMax}h (rimangono ${guard.weeklyHoursRemaining}h)` : "";
                        })()}
                      </p>
                    )}
                  </div>

                  {/* Input numero giorni */}
                  <div className="space-y-2">
                    <Label htmlFor="days-input">Numero Giorni Consecutivi</Label>
                    <Input
                      id="days-input"
                      type="number"
                      min={1}
                      max={7}
                      value={days}
                      onChange={(e) => setDays(Math.max(1, Math.min(7, parseInt(e.target.value) || 1)))}
                      disabled={createShiftMutation.isPending}
                      data-testid="input-days"
                    />
                    <p className="text-xs text-muted-foreground">
                      Il turno verrà creato a partire da {selectedCell && format(new Date(selectedCell.date), "dd/MM/yyyy")} per {days} {days === 1 ? "giorno" : "giorni"}
                    </p>
                  </div>

                  {/* Bottone crea turno */}
                  <Button
                    onClick={handleCreateShift}
                    disabled={!selectedGuardId || createShiftMutation.isPending || (availableGuards && availableGuards.length === 0)}
                    data-testid="button-create-shift"
                    className="w-full"
                  >
                    {createShiftMutation.isPending ? (
                      "Creazione in corso..."
                    ) : (
                      <>
                        <Plus className="h-4 w-4 mr-2" />
                        Crea Turno ({days} {days === 1 ? "giorno" : "giorni"})
                      </>
                    )}
                  </Button>
                </div>
              </div>
            </div>
          )}

          <DialogFooter>
            <Button variant="outline" onClick={() => setSelectedCell(null)}>
              Chiudi
            </Button>
            <Button onClick={navigateToOperationalPlanning} data-testid="button-edit-planning">
              <Edit className="h-4 w-4 mr-2" />
              Modifica in Pianificazione Operativa
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
