import { useState, useEffect } 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, Trash2, Clock, Copy } 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 {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { queryClient, apiRequest } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";
import type { GuardAvailability, Vehicle as VehicleDb } from "@shared/schema";

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

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

interface SiteData {
  siteId: string;
  siteName: string;
  serviceType: string;
  serviceStartTime: string;
  serviceEndTime: string;
  serviceHours: number;
  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;
  };
}

// Helper per formattare orario in formato italiano 24h (HH:MM)
// IMPORTANTE: Gli orari nel DB sono UTC, visualizzali in timezone Europe/Rome
const formatTime = (dateString: string) => {
  const date = new Date(dateString);
  return date.toLocaleTimeString("it-IT", { 
    hour: "2-digit", 
    minute: "2-digit", 
    hour12: false,
    timeZone: "Europe/Rome"  // Converti da UTC a Italy time
  });
};

// Helper per formattare data in formato italiano (gg/mm/aaaa)
const formatDateIT = (dateString: string) => {
  const date = new Date(dateString);
  return date.toLocaleDateString("it-IT");
};

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 assegnazione guardia
  const [selectedGuardId, setSelectedGuardId] = useState<string>("");
  const [selectedVehicleId, setSelectedVehicleId] = useState<string>("none");
  const [startTime, setStartTime] = useState<string>("06:00");
  const [durationHours, setDurationHours] = useState<number>(8);
  const [consecutiveDays, setConsecutiveDays] = useState<number>(1);
  const [showOvertimeGuards, setShowOvertimeGuards] = useState<boolean>(false);
  const [ccnlConfirmation, setCcnlConfirmation] = useState<{ message: string; data: any } | null>(null);
  const [showCopyWeekConfirmation, setShowCopyWeekConfirmation] = useState<boolean>(false);

  // 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();
    },
  });

  // Calcola start e end time per la query availability
  const getTimeSlot = () => {
    if (!selectedCell) return { start: "", end: "" };
    const [hours, minutes] = startTime.split(":").map(Number);
    const startDateTime = new Date(selectedCell.date);
    startDateTime.setHours(hours, minutes, 0, 0);
    
    const endDateTime = new Date(startDateTime);
    endDateTime.setHours(startDateTime.getHours() + durationHours);
    
    return {
      start: startDateTime.toISOString(),
      end: endDateTime.toISOString()
    };
  };

  // Query per guardie disponibili (solo quando dialog è aperto)
  const { data: availableGuards, isLoading: isLoadingGuards, refetch: refetchGuards } = useQuery<GuardAvailability[]>({
    queryKey: ["/api/guards/availability", selectedCell?.siteId, selectedLocation, startTime, durationHours],
    queryFn: async () => {
      if (!selectedCell) return [];
      const { start, end } = getTimeSlot();
      const response = await fetch(
        `/api/guards/availability?start=${encodeURIComponent(start)}&end=${encodeURIComponent(end)}&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
    staleTime: 0, // Dati sempre considerati stale, refetch ad ogni apertura dialog
  });
  
  // Query per veicoli disponibili (solo quando dialog è aperto)
  const { data: availableVehicles, isLoading: isLoadingVehicles } = useQuery<VehicleDb[]>({
    queryKey: ["/api/vehicles/available", selectedLocation],
    queryFn: async () => {
      if (!selectedCell) return [];
      const response = await fetch(`/api/vehicles/available?location=${selectedLocation}`);
      if (!response.ok) throw new Error("Failed to fetch available vehicles");
      return response.json();
    },
    enabled: !!selectedCell,
    staleTime: 0,
  });

  // Calcola dati aggiornati della cella selezionata (per auto-refresh dialog)
  const currentCellData = (() => {
    if (!selectedCell || !planningData) return selectedCell?.data;
    
    // Trova i dati freschi da planningData
    const day = planningData.days.find(d => d.date === selectedCell.date);
    if (!day) return selectedCell.data;
    
    const updatedSite = day.sites.find(s => s.siteId === selectedCell.siteId);
    return updatedSite || selectedCell.data;
  })();

  // Mutation per eliminare assegnazione guardia
  const deleteAssignmentMutation = useMutation({
    mutationFn: async (assignmentId: string) => {
      return apiRequest("DELETE", `/api/shift-assignments/${assignmentId}`, undefined);
    },
    onSuccess: async () => {
      // Invalida e refetch planning generale per aggiornare dialog
      await queryClient.invalidateQueries({ queryKey: ["/api/general-planning"] });
      await queryClient.invalidateQueries({ queryKey: ["/api/guards/availability"] });
      await queryClient.refetchQueries({ queryKey: ["/api/general-planning"] });
      
      toast({
        title: "Guardia rimossa",
        description: "L'assegnazione è stata eliminata con successo",
      });
    },
    onError: (error: any) => {
      toast({
        title: "Errore",
        description: "Impossibile eliminare l'assegnazione",
        variant: "destructive",
      });
    },
  });

  // Mutation per assegnare guardia con orari (anche multi-giorno)
  const assignGuardMutation = useMutation({
    mutationFn: async (data: { siteId: string; date: string; guardId: string; startTime: string; durationHours: number; consecutiveDays: number; vehicleId?: string; force?: boolean }) => {
      return apiRequest("POST", "/api/general-planning/assign-guard", data);
    },
    onSuccess: async () => {
      // Invalida cache planning generale, guardie e veicoli
      await queryClient.invalidateQueries({ queryKey: ["/api/general-planning"] });
      await queryClient.invalidateQueries({ queryKey: ["/api/guards/availability"] });
      await queryClient.invalidateQueries({ queryKey: ["/api/vehicles/available"] });
      
      // Refetch immediatamente guardie disponibili per aggiornare lista
      await refetchGuards();
      
      toast({
        title: "Guardia assegnata",
        description: "La guardia è stata assegnata con successo",
      });
      
      // Reset form (NON chiudere dialog per vedere lista aggiornata)
      setSelectedGuardId("");
      setSelectedVehicleId("");
      setCcnlConfirmation(null); // Reset dialog conferma se aperto
    },
    onError: (error: any, variables) => {
      // Parse error message from API response
      let errorMessage = "Impossibile assegnare la guardia";
      let errorType = "";
      
      if (error.message) {
        // Error format from apiRequest: "STATUS_CODE: {json_body}"
        const match = error.message.match(/^(\d+):\s*(.+)$/);
        if (match) {
          const statusCode = match[1];
          try {
            const parsed = JSON.parse(match[2]);
            errorMessage = parsed.message || errorMessage;
            errorType = parsed.type || "";
            
            // Se è un errore CCNL (409 con tipo CCNL_VIOLATION), mostra dialog conferma
            if (statusCode === "409" && errorType === "CCNL_VIOLATION") {
              setCcnlConfirmation({
                message: errorMessage,
                data: variables
              });
              return; // Non mostrare toast, mostra dialog
            }
          } catch {
            errorMessage = match[2];
          }
        } else {
          errorMessage = error.message;
        }
      }
      
      toast({
        title: "Errore Assegnazione",
        description: errorMessage,
        variant: "destructive",
      });
    },
  });

  // Mutation per copiare turni settimanali
  const copyWeekMutation = useMutation({
    mutationFn: async () => {
      return apiRequest("POST", "/api/shift-assignments/copy-week", {
        weekStart: format(weekStart, "yyyy-MM-dd"),
        location: selectedLocation,
      });
    },
    onSuccess: async (response: any) => {
      const data = await response.json();
      
      toast({
        title: "Settimana copiata!",
        description: `${data.copiedShifts} turni e ${data.copiedAssignments} assegnazioni copiate nella settimana successiva`,
      });
      
      // Invalida cache e naviga alla settimana successiva
      await queryClient.invalidateQueries({ queryKey: ["/api/general-planning"] });
      setWeekStart(addWeeks(weekStart, 1)); // Naviga alla settimana copiata
      setShowCopyWeekConfirmation(false);
    },
    onError: (error: any) => {
      let errorMessage = "Impossibile copiare la settimana";
      
      if (error.message) {
        const match = error.message.match(/^(\d+):\s*(.+)$/);
        if (match) {
          try {
            const parsed = JSON.parse(match[2]);
            errorMessage = parsed.message || errorMessage;
          } catch {
            errorMessage = match[2];
          }
        } else {
          errorMessage = error.message;
        }
      }
      
      toast({
        title: "Errore Copia Settimana",
        description: errorMessage,
        variant: "destructive",
      });
      
      setShowCopyWeekConfirmation(false);
    },
  });

  // Handler per submit form assegnazione guardia
  const handleAssignGuard = () => {
    if (!selectedCell || !selectedGuardId) return;
    
    assignGuardMutation.mutate({
      siteId: selectedCell.siteId,
      date: selectedCell.date,
      guardId: selectedGuardId,
      startTime,
      durationHours,
      consecutiveDays,
      ...(selectedVehicleId && selectedVehicleId !== "none" && { vehicleId: selectedVehicleId }),
    });
  };

  // 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 Fissi
          </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 flex-wrap">
              <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>
              
              <Button
                variant="default"
                onClick={() => setShowCopyWeekConfirmation(true)}
                disabled={isLoading || !planningData || copyWeekMutation.isPending}
                data-testid="button-copy-week"
              >
                <Copy className="h-4 w-4 mr-2" />
                {copyWeekMutation.isPending ? "Copia in corso..." : "Copia Turno Settimanale"}
              </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);
        setSelectedGuardId("");
        setStartTime("06:00");
        setDurationHours(8);
        setConsecutiveDays(1);
        setSelectedVehicleId("");
      }}>
        <DialogContent className="max-w-6xl max-h-[90vh] flex flex-col">
          <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 overflow-y-auto pr-2">
              {/* Form assegnazione guardia - SEMPRE IN ALTO E VISIBILE */}
              <div className="bg-accent/5 border border-accent/20 rounded-lg p-4 space-y-4">
                <div className="flex items-center gap-2 text-sm font-semibold">
                  <Plus className="h-4 w-4" />
                  Assegna Nuova Guardia
                </div>

                <div className="grid gap-4">
                  {/* Ora Inizio, Durata e Giorni */}
                  <div className="grid grid-cols-3 gap-4">
                    <div className="space-y-2">
                      <Label htmlFor="start-time">Ora Inizio</Label>
                      <Input
                        id="start-time"
                        type="time"
                        value={startTime}
                        onChange={(e) => setStartTime(e.target.value)}
                        disabled={assignGuardMutation.isPending}
                        data-testid="input-start-time"
                      />
                    </div>
                    <div className="space-y-2">
                      <Label htmlFor="duration">Durata (ore)</Label>
                      <Input
                        id="duration"
                        type="number"
                        min={1}
                        max={24}
                        value={durationHours}
                        onChange={(e) => setDurationHours(Math.max(1, Math.min(24, parseInt(e.target.value) || 8)))}
                        disabled={assignGuardMutation.isPending}
                        data-testid="input-duration"
                      />
                    </div>
                    <div className="space-y-2">
                      <Label htmlFor="consecutive-days">Giorni</Label>
                      <Input
                        id="consecutive-days"
                        type="number"
                        min={1}
                        max={30}
                        value={consecutiveDays}
                        onChange={(e) => setConsecutiveDays(Math.max(1, Math.min(30, parseInt(e.target.value) || 1)))}
                        disabled={assignGuardMutation.isPending}
                        data-testid="input-consecutive-days"
                      />
                    </div>
                  </div>
                  
                  {/* Ora fine calcolata */}
                  <div className="text-xs text-muted-foreground">
                    Ora fine: {(() => {
                      const [hours, minutes] = startTime.split(":").map(Number);
                      const endHour = (hours + durationHours) % 24;
                      return `${String(endHour).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
                    })()}
                  </div>

                  {/* Select guardia disponibile */}
                  {(() => {
                    // Filtra guardie: mostra solo con ore ordinarie se toggle è off
                    const filteredGuards = availableGuards?.filter(g => 
                      g.isAvailable && (showOvertimeGuards || !g.requiresOvertime)
                    ) || [];
                    
                    const hasOvertimeGuards = availableGuards?.some(g => g.requiresOvertime && g.isAvailable) || false;
                    
                    return (
                      <div className="space-y-2">
                        <div className="flex items-center justify-between">
                          <Label htmlFor="guard-select">Guardia Disponibile</Label>
                          {!isLoadingGuards && hasOvertimeGuards && (
                            <Button
                              variant="outline"
                              size="sm"
                              onClick={() => setShowOvertimeGuards(!showOvertimeGuards)}
                              className="h-7 text-xs"
                              data-testid="button-toggle-overtime"
                            >
                              {showOvertimeGuards ? "Nascondi" : "Mostra"} Straordinario
                            </Button>
                          )}
                        </div>
                        {isLoadingGuards ? (
                          <Skeleton className="h-10 w-full" />
                        ) : (
                          <>
                            <Select 
                              value={selectedGuardId} 
                              onValueChange={setSelectedGuardId}
                              disabled={assignGuardMutation.isPending}
                            >
                              <SelectTrigger id="guard-select" data-testid="select-guard">
                                <SelectValue placeholder="Seleziona guardia..." />
                              </SelectTrigger>
                              <SelectContent>
                                {filteredGuards.length > 0 ? (
                                  filteredGuards.map((guard) => (
                                    <SelectItem key={guard.guardId} value={guard.guardId}>
                                      {guard.guardName} ({guard.badgeNumber}) - {guard.ordinaryHoursRemaining}h ord.
                                      {guard.requiresOvertime && ` + ${guard.overtimeHoursRemaining}h strao.`}
                                      {guard.requiresOvertime && " 🔸"}
                                    </SelectItem>
                                  ))
                                ) : (
                                  <SelectItem value="no-guards" disabled>
                                    {showOvertimeGuards 
                                      ? "Nessuna guardia disponibile" 
                                      : "Nessuna guardia con ore ordinarie (prova 'Mostra Straordinario')"}
                                  </SelectItem>
                                )}
                              </SelectContent>
                            </Select>
                            {filteredGuards.length === 0 && !showOvertimeGuards && hasOvertimeGuards && (
                              <p className="text-xs text-muted-foreground">
                                ℹ️ Alcune guardie disponibili richiedono straordinario. Clicca "Mostra Straordinario" per vederle.
                              </p>
                            )}
                            {filteredGuards.length > 0 && selectedGuardId && (
                              <div className="text-xs space-y-1">
                                {(() => {
                                  const guard = availableGuards?.find(g => g.guardId === selectedGuardId);
                                  if (!guard) return null;
                                  return (
                                    <>
                                      <p className="text-muted-foreground">
                                        Ore ordinarie: {guard.ordinaryHoursRemaining}h / 40h disponibili
                                        {guard.requiresOvertime && ` • Straordinario: ${guard.overtimeHoursRemaining}h / 8h`}
                                      </p>
                                      <p className="text-muted-foreground">
                                        Ore assegnate: {guard.weeklyHoursAssigned}h / {guard.weeklyHoursMax}h (rimangono {guard.weeklyHoursRemaining}h)
                                      </p>
                                      {guard.nightHoursAssigned > 0 && (
                                        <p className="text-muted-foreground">
                                          Ore notturne: {guard.nightHoursAssigned}h / 48h settimanali
                                        </p>
                                      )}
                                      {guard.hasRestViolation && (
                                        <p className="text-yellow-600 dark:text-yellow-500 font-medium">
                                          ⚠️ Attenzione: riposo insufficiente dall'ultimo turno
                                        </p>
                                      )}
                                      {guard.conflicts && guard.conflicts.length > 0 && (
                                        <p className="text-destructive font-medium">
                                          ⚠️ Conflitto: {guard.conflicts.map((c: any) => 
                                            `${c.siteName} (${new Date(c.from).toLocaleTimeString('it-IT', {hour: '2-digit', minute:'2-digit'})} - ${new Date(c.to).toLocaleTimeString('it-IT', {hour: '2-digit', minute:'2-digit'})})`
                                          ).join(", ")}
                                        </p>
                                      )}
                                      {guard.unavailabilityReasons && guard.unavailabilityReasons.length > 0 && (
                                        <p className="text-yellow-600 dark:text-yellow-500">
                                          {guard.unavailabilityReasons.join(", ")}
                                        </p>
                                      )}
                                    </>
                                  );
                                })()}
                              </div>
                            )}
                          </>
                        )}
                      </div>
                    );
                  })()}
                  
                  {/* Select veicolo (opzionale) */}
                  <div className="space-y-2">
                    <Label htmlFor="vehicle-select">Veicolo (opzionale)</Label>
                    {isLoadingVehicles ? (
                      <Skeleton className="h-10 w-full" />
                    ) : (
                      <Select 
                        value={selectedVehicleId} 
                        onValueChange={setSelectedVehicleId}
                        disabled={assignGuardMutation.isPending}
                      >
                        <SelectTrigger id="vehicle-select" data-testid="select-vehicle">
                          <SelectValue placeholder="Nessun veicolo" />
                        </SelectTrigger>
                        <SelectContent>
                          <SelectItem value="none">Nessun veicolo</SelectItem>
                          {availableVehicles && availableVehicles.length > 0 ? (
                            availableVehicles.map((vehicle) => (
                              <SelectItem key={vehicle.id} value={vehicle.id}>
                                {vehicle.licensePlate} - {vehicle.brand} {vehicle.model}
                              </SelectItem>
                            ))
                          ) : (
                            <SelectItem value="no-vehicles" disabled>
                              Nessun veicolo disponibile
                            </SelectItem>
                          )}
                        </SelectContent>
                      </Select>
                    )}
                  </div>

                  {/* Bottone assegna */}
                  <Button
                    onClick={handleAssignGuard}
                    disabled={!selectedGuardId || assignGuardMutation.isPending || (availableGuards && availableGuards.length === 0)}
                    data-testid="button-assign-guard"
                    className="w-full"
                  >
                    {assignGuardMutation.isPending ? (
                      "Assegnazione in corso..."
                    ) : (
                      <>
                        <Plus className="h-4 w-4 mr-2" />
                        Assegna Guardia
                      </>
                    )}
                  </Button>
                </div>
              </div>

              {/* Guardie già assegnate - fuori dal form box per evitare di nascondere il form */}
              {currentCellData && currentCellData.guards.length > 0 && (
                <div className="space-y-2">
                  <h3 className="text-sm font-semibold flex items-center gap-2">
                    <Users className="h-4 w-4" />
                    Guardie Già Assegnate ({currentCellData.guards.length})
                  </h3>
                  <div className="grid gap-2">
                    {currentCellData.guards.map((guard, idx) => (
                      <div key={idx} className="flex items-start justify-between gap-2 bg-muted/30 p-2.5 rounded border">
                        <div className="flex-1 space-y-1">
                          <div className="flex items-center gap-2">
                            <span className="font-medium text-sm">{guard.guardName}</span>
                            <Badge variant="outline" className="text-xs">#{guard.badgeNumber}</Badge>
                          </div>
                          <div className="flex items-center gap-2 text-xs text-muted-foreground">
                            <Clock className="h-3 w-3" />
                            <span>{formatTime(guard.plannedStartTime)} - {formatTime(guard.plannedEndTime)}</span>
                            <span className="font-medium">({guard.hours}h)</span>
                          </div>
                        </div>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-7 w-7 text-destructive hover:text-destructive hover:bg-destructive/10"
                          onClick={() => {
                            if (confirm(`Confermi di voler rimuovere ${guard.guardName} da questo turno?`)) {
                              deleteAssignmentMutation.mutate(guard.assignmentId);
                            }
                          }}
                          disabled={deleteAssignmentMutation.isPending}
                          data-testid={`button-delete-assignment-${guard.guardId}`}
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Separator */}
              <div className="border-t" />

              {/* Info turni esistenti */}
              <div className="space-y-4">
                <h3 className="font-semibold text-sm">Informazioni Servizio</h3>
                
                {/* Tipo servizio e orario */}
                {currentCellData && (
                  <div className="bg-muted/30 p-3 rounded-md space-y-2">
                    <div className="flex items-center justify-between">
                      <span className="text-sm text-muted-foreground">Tipo Servizio</span>
                      <Badge variant="outline">{currentCellData.serviceType}</Badge>
                    </div>
                    <div className="flex items-center justify-between">
                      <span className="text-sm text-muted-foreground">Orario Servizio</span>
                      <span className="text-sm font-medium">{currentCellData.serviceStartTime} - {currentCellData.serviceEndTime}</span>
                    </div>
                    <div className="flex items-center justify-between">
                      <span className="text-sm text-muted-foreground">Ore Richieste</span>
                      <span className="text-sm font-bold">{currentCellData.serviceHours}h</span>
                    </div>
                  </div>
                )}
                
                <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">{currentCellData?.shiftsCount || 0}</p>
                  </div>
                  <div>
                    <p className="text-sm text-muted-foreground">Ore Assegnate</p>
                    <p className="text-2xl font-bold">{currentCellData?.totalShiftHours || 0}h</p>
                  </div>
                </div>

                {/* Guardie mancanti */}
                {currentCellData && currentCellData.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">{currentCellData.missingGuards}</span>{" "}
                      {currentCellData.missingGuards === 1 ? "guardia" : "guardie"} per coprire completamente il servizio
                      (calcolato su {currentCellData.totalShiftHours}h con max 9h per guardia e {currentCellData.minGuards} {currentCellData.minGuards === 1 ? "guardia minima" : "guardie minime"} contemporanee)
                    </p>
                  </div>
                )}

                {/* Veicoli */}
                {currentCellData && currentCellData.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 ({currentCellData.vehicles.length})
                    </div>
                    <div className="grid gap-2">
                      {currentCellData.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>
                )}

                {/* No turni */}
                {selectedCell.data.shiftsCount === 0 && (
                  <div className="text-center py-6 text-muted-foreground">
                    <Calendar className="h-10 w-10 mx-auto mb-3 opacity-50" />
                    <p className="text-sm">Nessun turno pianificato per questa data</p>
                    <p className="text-xs mt-1">Usa il modulo sopra per assegnare la prima guardia</p>
                  </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>

      {/* Dialog conferma forzatura CCNL */}
      <AlertDialog open={!!ccnlConfirmation} onOpenChange={() => setCcnlConfirmation(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle className="flex items-center gap-2">
              <AlertTriangle className="h-5 w-5 text-yellow-600" />
              Superamento Limite CCNL
            </AlertDialogTitle>
            <AlertDialogDescription className="space-y-2">
              <p className="text-foreground font-medium">
                {ccnlConfirmation?.message}
              </p>
              <p className="text-sm">
                Vuoi forzare comunque l'assegnazione? L'operazione verrà registrata e potrai consultarla nei report.
              </p>
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel data-testid="button-cancel-force">Annulla</AlertDialogCancel>
            <AlertDialogAction
              onClick={() => {
                if (ccnlConfirmation) {
                  assignGuardMutation.mutate({
                    ...ccnlConfirmation.data,
                    force: true
                  });
                }
              }}
              data-testid="button-confirm-force"
              className="bg-yellow-600 hover:bg-yellow-700"
            >
              Forza Assegnazione
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* Dialog conferma copia settimana */}
      <AlertDialog open={showCopyWeekConfirmation} onOpenChange={setShowCopyWeekConfirmation}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle className="flex items-center gap-2">
              <Copy className="h-5 w-5" />
              Copia Turno Settimanale
            </AlertDialogTitle>
            <AlertDialogDescription asChild>
              <div className="space-y-3">
                <p className="text-foreground font-medium">
                  Vuoi copiare tutti i turni della settimana corrente nella settimana successiva?
                </p>
                {planningData && (
                  <div className="space-y-2 bg-muted/30 p-3 rounded-md">
                    <div className="flex items-center justify-between text-sm">
                      <span className="text-muted-foreground">Settimana corrente:</span>
                      <span className="font-medium">
                        {format(new Date(planningData.weekStart), "dd MMM", { locale: it })} -{" "}
                        {format(new Date(planningData.weekEnd), "dd MMM yyyy", { locale: it })}
                      </span>
                    </div>
                    <div className="flex items-center justify-between text-sm">
                      <span className="text-muted-foreground">Verrà copiata in:</span>
                      <span className="font-medium">
                        {format(addWeeks(new Date(planningData.weekStart), 1), "dd MMM", { locale: it })} -{" "}
                        {format(addWeeks(new Date(planningData.weekEnd), 1), "dd MMM yyyy", { locale: it })}
                      </span>
                    </div>
                    <div className="flex items-center justify-between text-sm">
                      <span className="text-muted-foreground">Sede:</span>
                      <span className="font-medium">{formatLocation(selectedLocation)}</span>
                    </div>
                  </div>
                )}
                <p className="text-sm text-muted-foreground">
                  Tutti i turni e le assegnazioni guardie verranno duplicati con le stesse caratteristiche (orari, dotazioni, veicoli).
                </p>
              </div>
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel data-testid="button-cancel-copy-week">Annulla</AlertDialogCancel>
            <AlertDialogAction
              onClick={() => copyWeekMutation.mutate()}
              data-testid="button-confirm-copy-week"
              disabled={copyWeekMutation.isPending}
            >
              {copyWeekMutation.isPending ? "Copia in corso..." : "Conferma Copia"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
