import { useState } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { ShiftWithDetails, InsertShift, Site, GuardWithCertifications } from "@shared/schema";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { insertShiftFormSchema } from "@shared/schema";
import { Plus, Calendar, MapPin, Users, Clock, UserPlus, X, Shield, Car, Heart, Flame, Pencil } from "lucide-react";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";
import { StatusBadge } from "@/components/status-badge";
import { Skeleton } from "@/components/ui/skeleton";
import { format } from "date-fns";
import { it } from "date-fns/locale";
import { Badge } from "@/components/ui/badge";

export default function Shifts() {
  const { toast } = useToast();
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [selectedShift, setSelectedShift] = useState<ShiftWithDetails | null>(null);
  const [isAssignDialogOpen, setIsAssignDialogOpen] = useState(false);
  const [editingShift, setEditingShift] = useState<ShiftWithDetails | null>(null);

  const { data: shifts, isLoading: shiftsLoading } = useQuery<ShiftWithDetails[]>({
    queryKey: ["/api/shifts"],
  });

  const { data: sites } = useQuery<Site[]>({
    queryKey: ["/api/sites"],
  });

  const { data: guards } = useQuery<GuardWithCertifications[]>({
    queryKey: ["/api/guards"],
  });

  const form = useForm({
    resolver: zodResolver(insertShiftFormSchema),
    defaultValues: {
      siteId: "",
      startTime: "",
      endTime: "",
      status: "planned" as const,
    },
  });

  const editForm = useForm({
    resolver: zodResolver(insertShiftFormSchema),
    defaultValues: {
      siteId: "",
      startTime: "",
      endTime: "",
      status: "planned" as const,
    },
  });

  const createMutation = useMutation({
    mutationFn: async (data: InsertShift) => {
      return await apiRequest("POST", "/api/shifts", data);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/shifts"] });
      toast({
        title: "Turno creato",
        description: "Il turno è stato pianificato con successo",
      });
      setIsDialogOpen(false);
      form.reset();
    },
    onError: (error) => {
      toast({
        title: "Errore",
        description: error.message,
        variant: "destructive",
      });
    },
  });

  const onSubmit = (data: InsertShift) => {
    createMutation.mutate(data);
  };

  const assignGuardMutation = useMutation({
    mutationFn: async ({ shiftId, guardId }: { shiftId: string; guardId: string }) => {
      return await apiRequest("POST", "/api/shift-assignments", { shiftId, guardId });
    },
    onSuccess: async () => {
      // Invalidate and wait for refetch to complete
      await queryClient.refetchQueries({ queryKey: ["/api/shifts"] });
      // Now get the fresh data
      const updatedShifts = queryClient.getQueryData<ShiftWithDetails[]>(["/api/shifts"]);
      if (selectedShift && updatedShifts) {
        const updatedShift = updatedShifts.find(s => s.id === selectedShift.id);
        if (updatedShift) {
          setSelectedShift(updatedShift);
        }
      }
      toast({
        title: "Guardia assegnata",
        description: "La guardia è stata assegnata al turno con successo",
      });
    },
    onError: (error) => {
      toast({
        title: "Errore",
        description: error.message,
        variant: "destructive",
      });
    },
  });

  const removeAssignmentMutation = useMutation({
    mutationFn: async (assignmentId: string) => {
      return await apiRequest("DELETE", `/api/shift-assignments/${assignmentId}`);
    },
    onSuccess: async () => {
      // Invalidate and wait for refetch to complete
      await queryClient.refetchQueries({ queryKey: ["/api/shifts"] });
      // Now get the fresh data
      const updatedShifts = queryClient.getQueryData<ShiftWithDetails[]>(["/api/shifts"]);
      if (selectedShift && updatedShifts) {
        const updatedShift = updatedShifts.find(s => s.id === selectedShift.id);
        if (updatedShift) {
          setSelectedShift(updatedShift);
        }
      }
      toast({
        title: "Assegnazione rimossa",
        description: "La guardia è stata rimossa dal turno",
      });
    },
    onError: (error) => {
      toast({
        title: "Errore",
        description: error.message,
        variant: "destructive",
      });
    },
  });

  const updateMutation = useMutation({
    mutationFn: async ({ id, data }: { id: string; data: InsertShift }) => {
      return await apiRequest("PATCH", `/api/shifts/${id}`, data);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/shifts"] });
      toast({
        title: "Turno aggiornato",
        description: "Il turno è stato aggiornato con successo",
      });
      setEditingShift(null);
      editForm.reset();
    },
    onError: (error) => {
      toast({
        title: "Errore",
        description: error.message,
        variant: "destructive",
      });
    },
  });

  const handleAssignGuard = (guardId: string) => {
    if (selectedShift) {
      assignGuardMutation.mutate({ shiftId: selectedShift.id, guardId });
    }
  };

  const handleRemoveAssignment = (assignmentId: string) => {
    removeAssignmentMutation.mutate(assignmentId);
  };

  const onEditSubmit = (data: InsertShift) => {
    if (editingShift) {
      updateMutation.mutate({ id: editingShift.id, data });
    }
  };

  const openEditDialog = (shift: ShiftWithDetails) => {
    const formatForInput = (date: Date | string) => {
      const d = new Date(date);
      return d.toISOString().slice(0, 16);
    };

    setEditingShift(shift);
    editForm.reset({
      siteId: shift.siteId,
      startTime: formatForInput(shift.startTime),
      endTime: formatForInput(shift.endTime),
      status: shift.status,
    });
  };

  const isGuardAssigned = (guardId: string) => {
    return selectedShift?.assignments.some(a => a.guardId === guardId) || false;
  };

  const canGuardBeAssigned = (guard: GuardWithCertifications) => {
    if (!selectedShift) return false;
    const site = sites?.find(s => s.id === selectedShift.siteId);
    if (!site) return true;

    if (site.requiresArmed && !guard.isArmed) return false;
    if (site.requiresDriverLicense && !guard.hasDriverLicense) return false;

    return true;
  };

  const getStatusLabel = (status: string) => {
    const labels: Record<string, string> = {
      planned: "Pianificato",
      active: "Attivo",
      completed: "Completato",
      cancelled: "Annullato",
    };
    return labels[status] || status;
  };

  const getStatusVariant = (status: string): "active" | "inactive" | "pending" | "completed" => {
    const variants: Record<string, "active" | "inactive" | "pending" | "completed"> = {
      planned: "pending",
      active: "active",
      completed: "completed",
      cancelled: "inactive",
    };
    return variants[status] || "inactive";
  };

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-semibold mb-2">Pianificazione Turni</h1>
          <p className="text-muted-foreground">
            Calendario 24/7 con assegnazione guardie
          </p>
        </div>
        <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
          <DialogTrigger asChild>
            <Button data-testid="button-add-shift">
              <Plus className="h-4 w-4 mr-2" />
              Nuovo Turno
            </Button>
          </DialogTrigger>
          <DialogContent className="max-w-2xl">
            <DialogHeader>
              <DialogTitle>Nuovo Turno</DialogTitle>
              <DialogDescription>
                Pianifica un nuovo turno di servizio
              </DialogDescription>
            </DialogHeader>
            <Form {...form}>
              <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
                <FormField
                  control={form.control}
                  name="siteId"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Sito</FormLabel>
                      <Select onValueChange={field.onChange} defaultValue={field.value}>
                        <FormControl>
                          <SelectTrigger data-testid="select-site">
                            <SelectValue placeholder="Seleziona sito" />
                          </SelectTrigger>
                        </FormControl>
                        <SelectContent>
                          {sites?.map((site) => (
                            <SelectItem key={site.id} value={site.id}>
                              {site.name}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <div className="grid grid-cols-2 gap-4">
                  <FormField
                    control={form.control}
                    name="startTime"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Inizio</FormLabel>
                        <FormControl>
                          <input
                            type="datetime-local"
                            className="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm"
                            value={field.value}
                            onChange={(e) => field.onChange(e.target.value)}
                            data-testid="input-start-time"
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />

                  <FormField
                    control={form.control}
                    name="endTime"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Fine</FormLabel>
                        <FormControl>
                          <input
                            type="datetime-local"
                            className="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm"
                            value={field.value}
                            onChange={(e) => field.onChange(e.target.value)}
                            data-testid="input-end-time"
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </div>

                <div className="flex gap-3 pt-4">
                  <Button
                    type="button"
                    variant="outline"
                    onClick={() => setIsDialogOpen(false)}
                    className="flex-1"
                    data-testid="button-cancel"
                  >
                    Annulla
                  </Button>
                  <Button
                    type="submit"
                    className="flex-1"
                    disabled={createMutation.isPending}
                    data-testid="button-submit-shift"
                  >
                    {createMutation.isPending ? "Creazione..." : "Crea Turno"}
                  </Button>
                </div>
              </form>
            </Form>
          </DialogContent>
        </Dialog>
      </div>

      {shiftsLoading ? (
        <div className="space-y-4">
          <Skeleton className="h-32" />
          <Skeleton className="h-32" />
          <Skeleton className="h-32" />
        </div>
      ) : shifts && shifts.length > 0 ? (
        <div className="space-y-4">
          {shifts.map((shift) => (
            <Card key={shift.id} className="hover-elevate" data-testid={`card-shift-${shift.id}`}>
              <CardHeader>
                <div className="flex items-start justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <CardTitle className="text-lg flex items-center gap-2">
                      <MapPin className="h-5 w-5 text-muted-foreground" />
                      {shift.site.name}
                    </CardTitle>
                    <CardDescription className="mt-2 flex items-center gap-2">
                      <Clock className="h-4 w-4" />
                      {format(new Date(shift.startTime), "dd/MM/yyyy HH:mm", { locale: it })} -{" "}
                      {format(new Date(shift.endTime), "HH:mm", { locale: it })}
                    </CardDescription>
                  </div>
                  <div className="flex items-center gap-2">
                    <StatusBadge status={getStatusVariant(shift.status)}>
                      {getStatusLabel(shift.status)}
                    </StatusBadge>
                    <Button
                      size="icon"
                      variant="ghost"
                      onClick={() => openEditDialog(shift)}
                      data-testid={`button-edit-shift-${shift.id}`}
                    >
                      <Pencil className="h-4 w-4" />
                    </Button>
                  </div>
                </div>
              </CardHeader>
              <CardContent>
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-2 text-sm text-muted-foreground">
                    <Users className="h-4 w-4" />
                    <span>
                      {shift.assignments.length > 0
                        ? `${shift.assignments.length} guardie assegnate`
                        : "Nessuna guardia assegnata"}
                    </span>
                  </div>
                  {shift.status === "planned" && (
                    <Button
                      size="sm"
                      variant="outline"
                      onClick={() => {
                        setSelectedShift(shift);
                        setIsAssignDialogOpen(true);
                      }}
                      data-testid={`button-assign-guards-${shift.id}`}
                    >
                      <UserPlus className="h-4 w-4 mr-2" />
                      Assegna Guardie
                    </Button>
                  )}
                </div>
                {shift.assignments.length > 0 && (
                  <div className="mt-3 flex flex-wrap gap-2">
                    {shift.assignments.map((assignment) => (
                      <div
                        key={assignment.id}
                        className="flex items-center gap-1 text-xs bg-secondary text-secondary-foreground px-2 py-1 rounded-md"
                        data-testid={`assignment-${assignment.id}`}
                      >
                        <span>
                          {assignment.guard.user?.firstName} {assignment.guard.user?.lastName}
                        </span>
                        {shift.status === "planned" && (
                          <button
                            onClick={() => handleRemoveAssignment(assignment.id)}
                            className="ml-1 hover:text-destructive"
                            data-testid={`button-remove-assignment-${assignment.id}`}
                          >
                            <X className="h-3 w-3" />
                          </button>
                        )}
                      </div>
                    ))}
                  </div>
                )}
              </CardContent>
            </Card>
          ))}
        </div>
      ) : (
        <Card>
          <CardContent className="flex flex-col items-center justify-center py-16">
            <Calendar className="h-12 w-12 text-muted-foreground mb-4" />
            <p className="text-lg font-medium mb-2">Nessun turno pianificato</p>
            <p className="text-sm text-muted-foreground mb-4">
              Inizia pianificando il primo turno di servizio
            </p>
          </CardContent>
        </Card>
      )}

      {/* Assignment Dialog */}
      <Dialog open={isAssignDialogOpen} onOpenChange={setIsAssignDialogOpen}>
        <DialogContent className="max-w-3xl max-h-[80vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Assegna Guardie al Turno</DialogTitle>
            <DialogDescription>
              {selectedShift && (
                <>
                  {selectedShift.site.name} -{" "}
                  {format(new Date(selectedShift.startTime), "dd/MM/yyyy HH:mm", { locale: it })}
                </>
              )}
            </DialogDescription>
          </DialogHeader>

          {selectedShift && (
            <div className="space-y-4">
              {/* Site Requirements */}
              <div className="p-4 bg-muted rounded-lg">
                <h3 className="font-medium mb-2">Requisiti Sito</h3>
                <div className="flex flex-wrap gap-2">
                  {selectedShift.site.requiresArmed && (
                    <Badge variant="outline">
                      <Shield className="h-3 w-3 mr-1" />
                      Armato richiesto
                    </Badge>
                  )}
                  {selectedShift.site.requiresDriverLicense && (
                    <Badge variant="outline">
                      <Car className="h-3 w-3 mr-1" />
                      Patente richiesta
                    </Badge>
                  )}
                  <Badge variant="outline">
                    Min. {selectedShift.site.minGuards} guardie
                  </Badge>
                </div>
              </div>

              {/* Guards List */}
              <div className="space-y-2">
                <h3 className="font-medium">Guardie Disponibili</h3>
                {guards && guards.length > 0 ? (
                  <div className="space-y-2">
                    {guards.map((guard) => {
                      const assigned = isGuardAssigned(guard.id);
                      const canAssign = canGuardBeAssigned(guard);

                      return (
                        <div
                          key={guard.id}
                          className="flex items-center justify-between p-3 border rounded-lg"
                          data-testid={`guard-option-${guard.id}`}
                        >
                          <div className="flex-1">
                            <div className="flex items-center gap-2">
                              <p className="font-medium">
                                {guard.user?.firstName} {guard.user?.lastName}
                              </p>
                              <span className="text-xs text-muted-foreground font-mono">
                                #{guard.badgeNumber}
                              </span>
                            </div>
                            <div className="flex gap-1 mt-1">
                              {guard.isArmed && (
                                <Badge variant="secondary" className="text-xs">
                                  <Shield className="h-3 w-3 mr-1" />
                                  Armato
                                </Badge>
                              )}
                              {guard.hasDriverLicense && (
                                <Badge variant="secondary" className="text-xs">
                                  <Car className="h-3 w-3 mr-1" />
                                  Patente
                                </Badge>
                              )}
                              {guard.hasFirstAid && (
                                <Badge variant="secondary" className="text-xs">
                                  <Heart className="h-3 w-3 mr-1" />
                                  Primo Soccorso
                                </Badge>
                              )}
                              {guard.hasFireSafety && (
                                <Badge variant="secondary" className="text-xs">
                                  <Flame className="h-3 w-3 mr-1" />
                                  Antincendio
                                </Badge>
                              )}
                            </div>
                          </div>
                          <Button
                            size="sm"
                            variant={assigned ? "secondary" : "default"}
                            onClick={() => handleAssignGuard(guard.id)}
                            disabled={assigned || !canAssign}
                            data-testid={`button-assign-guard-${guard.id}`}
                          >
                            {assigned ? "Assegnato" : canAssign ? "Assegna" : "Non idoneo"}
                          </Button>
                        </div>
                      );
                    })}
                  </div>
                ) : (
                  <p className="text-sm text-muted-foreground">Nessuna guardia disponibile</p>
                )}
              </div>
            </div>
          )}
        </DialogContent>
      </Dialog>

      {/* Edit Shift Dialog */}
      <Dialog open={!!editingShift} onOpenChange={(open) => !open && setEditingShift(null)}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>Modifica Turno</DialogTitle>
            <DialogDescription>
              Modifica i dati del turno presso {editingShift?.site.name}
            </DialogDescription>
          </DialogHeader>
          <Form {...editForm}>
            <form onSubmit={editForm.handleSubmit(onEditSubmit)} className="space-y-4">
              <FormField
                control={editForm.control}
                name="siteId"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Sito</FormLabel>
                    <Select onValueChange={field.onChange} defaultValue={field.value}>
                      <FormControl>
                        <SelectTrigger data-testid="select-edit-site">
                          <SelectValue placeholder="Seleziona sito" />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        {sites?.map((site) => (
                          <SelectItem key={site.id} value={site.id}>
                            {site.name}
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <div className="grid grid-cols-2 gap-4">
                <FormField
                  control={editForm.control}
                  name="startTime"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Inizio</FormLabel>
                      <FormControl>
                        <input
                          type="datetime-local"
                          className="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm"
                          value={field.value}
                          onChange={(e) => field.onChange(e.target.value)}
                          data-testid="input-edit-start-time"
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />

                <FormField
                  control={editForm.control}
                  name="endTime"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Fine</FormLabel>
                      <FormControl>
                        <input
                          type="datetime-local"
                          className="flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm"
                          value={field.value}
                          onChange={(e) => field.onChange(e.target.value)}
                          data-testid="input-edit-end-time"
                        />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              </div>

              <FormField
                control={editForm.control}
                name="status"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Stato Turno</FormLabel>
                    <Select onValueChange={field.onChange} defaultValue={field.value}>
                      <FormControl>
                        <SelectTrigger data-testid="select-edit-status">
                          <SelectValue placeholder="Seleziona stato" />
                        </SelectTrigger>
                      </FormControl>
                      <SelectContent>
                        <SelectItem value="planned">Pianificato</SelectItem>
                        <SelectItem value="active">Attivo</SelectItem>
                        <SelectItem value="completed">Completato</SelectItem>
                        <SelectItem value="cancelled">Annullato</SelectItem>
                      </SelectContent>
                    </Select>
                    <FormMessage />
                  </FormItem>
                )}
              />

              <div className="flex gap-3 pt-4">
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => setEditingShift(null)}
                  className="flex-1"
                  data-testid="button-edit-shift-cancel"
                >
                  Annulla
                </Button>
                <Button
                  type="submit"
                  className="flex-1"
                  disabled={updateMutation.isPending}
                  data-testid="button-submit-edit-shift"
                >
                  {updateMutation.isPending ? "Aggiornamento..." : "Salva Modifiche"}
                </Button>
              </div>
            </form>
          </Form>
        </DialogContent>
      </Dialog>
    </div>
  );
}
