import { useState, useMemo, useRef, useEffect } from "react";
import { useQuery, useMutation } from "@tanstack/react-query";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Calendar, MapPin, User, Car, Clock, Navigation, ListOrdered } from "lucide-react";
import { format, parseISO, isValid } from "date-fns";
import { it } from "date-fns/locale";
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
import L from 'leaflet';
import { useToast } from "@/hooks/use-toast";
import { apiRequest } from "@/lib/queryClient";
import { queryClient } from "@/lib/queryClient";

// Fix Leaflet default icon issue with Webpack
delete (L.Icon.Default.prototype as any)._getIconUrl;

// Icona blu standard per siti non in route
const blueIcon = new L.Icon({
  iconRetinaUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png',
  iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png',
  shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
  iconSize: [25, 41],
  iconAnchor: [12, 41],
  popupAnchor: [1, -34],
  shadowSize: [41, 41]
});

// Icona verde per marker selezionati nella patrol route
const greenIcon = new L.Icon({
  iconRetinaUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
  iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-green.png',
  shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
  iconSize: [25, 41],
  iconAnchor: [12, 41],
  popupAnchor: [1, -34],
  shadowSize: [41, 41]
});

type Location = "roccapiemonte" | "milano" | "roma";

type MobileSite = {
  id: string;
  name: string;
  address: string;
  serviceTypeId: string | null;
  serviceTypeName: string | null;
  location: Location;
  latitude: string | null;
  longitude: string | null;
};

type AvailableGuard = {
  id: string;
  firstName: string;
  lastName: string;
  badgeNumber: string;
  location: Location;
  weeklyHours: number;
  availableHours: number;
};

// Componente per controllare la mappa da fuori
function MapController({ center, zoom }: { center: [number, number] | null; zoom: number }) {
  const map = useMap();
  
  useEffect(() => {
    if (center) {
      map.flyTo(center, zoom, {
        duration: 1.5,
      });
    }
  }, [center, zoom, map]);
  
  return null;
}

export default function PlanningMobile() {
  const { toast } = useToast();
  const [selectedDate, setSelectedDate] = useState(format(new Date(), "yyyy-MM-dd"));
  const [selectedLocation, setSelectedLocation] = useState<Location>("roccapiemonte");
  const [selectedGuardId, setSelectedGuardId] = useState<string>("all");
  const [mapCenter, setMapCenter] = useState<[number, number] | null>(null);
  const [mapZoom, setMapZoom] = useState(12);
  const [patrolRoute, setPatrolRoute] = useState<MobileSite[]>([]);

  // Query siti mobile per location
  const { data: mobileSites, isLoading: sitesLoading } = useQuery<MobileSite[]>({
    queryKey: ["/api/planning-mobile/sites", selectedLocation],
    queryFn: async () => {
      const response = await fetch(`/api/planning-mobile/sites?location=${selectedLocation}`);
      if (!response.ok) {
        throw new Error("Failed to fetch mobile sites");
      }
      return response.json();
    },
    enabled: !!selectedLocation,
  });

  // Query guardie disponibili per location e data
  const { data: availableGuards, isLoading: guardsLoading } = useQuery<AvailableGuard[]>({
    queryKey: ["/api/planning-mobile/guards", selectedLocation, selectedDate],
    queryFn: async () => {
      const response = await fetch(`/api/planning-mobile/guards?location=${selectedLocation}&date=${selectedDate}`);
      if (!response.ok) {
        throw new Error("Failed to fetch available guards");
      }
      return response.json();
    },
    enabled: !!selectedLocation && !!selectedDate,
  });

  // Query patrol routes esistenti per guardia selezionata e data
  const { data: existingPatrolRoutes } = useQuery<any[]>({
    queryKey: ["/api/patrol-routes", selectedGuardId, selectedDate, selectedLocation],
    queryFn: async () => {
      const params = new URLSearchParams();
      if (selectedGuardId && selectedGuardId !== "all") {
        params.set("guardId", selectedGuardId);
      }
      params.set("date", selectedDate);
      params.set("location", selectedLocation);
      
      const response = await fetch(`/api/patrol-routes?${params.toString()}`);
      if (!response.ok) throw new Error("Failed to fetch patrol routes");
      return response.json();
    },
    enabled: !!selectedDate && !!selectedLocation,
  });

  const locationLabels: Record<Location, string> = {
    roccapiemonte: "Roccapiemonte",
    milano: "Milano",
    roma: "Roma",
  };

  const locationColors: Record<Location, string> = {
    roccapiemonte: "bg-blue-500",
    milano: "bg-green-500",
    roma: "bg-purple-500",
  };

  // Coordinate di default per centrare la mappa sulla location selezionata
  const locationCenters: Record<Location, [number, number]> = {
    roccapiemonte: [40.8167, 14.6167], // Roccapiemonte, Salerno
    milano: [45.4642, 9.1900], // Milano
    roma: [41.9028, 12.4964], // Roma
  };

  // Filtra siti con coordinate valide per la mappa
  const sitesWithCoordinates = useMemo(() => {
    return mobileSites?.filter((site) => 
      site.latitude !== null && 
      site.longitude !== null &&
      !isNaN(parseFloat(site.latitude)) &&
      !isNaN(parseFloat(site.longitude))
    ) || [];
  }, [mobileSites]);

  // Trova guardia selezionata
  const selectedGuard = useMemo(() => {
    if (selectedGuardId === "all") return null;
    return availableGuards?.find(g => g.id === selectedGuardId) || null;
  }, [selectedGuardId, availableGuards]);

  // Funzione per zoomare su un sito
  const handleZoomToSite = (site: MobileSite) => {
    if (site.latitude && site.longitude) {
      setMapCenter([parseFloat(site.latitude), parseFloat(site.longitude)]);
      setMapZoom(16); // Zoom ravvicinato
      toast({
        title: "Mappa centrata",
        description: `Visualizzazione di ${site.name}`,
      });
    } else {
      toast({
        title: "Coordinate mancanti",
        description: "Questo sito non ha coordinate GPS",
        variant: "destructive",
      });
    }
  };

  // Funzione per assegnare guardia a un sito
  const handleAssignGuard = (site: MobileSite) => {
    if (!selectedGuard) {
      toast({
        title: "Guardia non selezionata",
        description: "Seleziona una guardia dal filtro in alto",
        variant: "destructive",
      });
      return;
    }

    toast({
      title: "Guardia assegnata",
      description: `${site.name} assegnato a ${selectedGuard.firstName} ${selectedGuard.lastName}`,
    });
  };

  // Funzione per aggiungere sito alla patrol route
  const handleAddToRoute = (site: MobileSite) => {
    if (!selectedGuard) {
      toast({
        title: "Seleziona una guardia",
        description: "Prima seleziona una guardia per creare il turno pattuglia",
        variant: "destructive",
      });
      return;
    }

    // Controlla se il sito è già nella route
    const alreadyInRoute = patrolRoute.some(s => s.id === site.id);
    if (alreadyInRoute) {
      toast({
        title: "Sito già in sequenza",
        description: `${site.name} è già nella sequenza di pattuglia`,
        variant: "destructive",
      });
      return;
    }

    setPatrolRoute([...patrolRoute, site]);
    toast({
      title: "Sito aggiunto alla sequenza",
      description: `${site.name} - Tappa ${patrolRoute.length + 1} di ${patrolRoute.length + 1}`,
    });
  };

  // Funzione per rimuovere sito dalla route
  const handleRemoveFromRoute = (siteId: string) => {
    setPatrolRoute(patrolRoute.filter(s => s.id !== siteId));
    toast({
      title: "Sito rimosso",
      description: "Sito rimosso dalla sequenza di pattuglia",
    });
  };

  // Mutation per salvare patrol route
  const savePatrolRouteMutation = useMutation({
    mutationFn: async (data: any) => {
      const response = await apiRequest("POST", "/api/patrol-routes", data);
      return response.json();
    },
    onSuccess: () => {
      toast({
        title: "Turno pattuglia salvato",
        description: `${patrolRoute.length} tappe assegnate a ${selectedGuard?.firstName} ${selectedGuard?.lastName}`,
      });
      setPatrolRoute([]);
      queryClient.invalidateQueries({ queryKey: ["/api/patrol-routes"] });
    },
    onError: (error: any) => {
      toast({
        title: "Errore salvataggio",
        description: error.message || "Impossibile salvare il turno pattuglia",
        variant: "destructive",
      });
    },
  });

  // Funzione per salvare il turno pattuglia
  const handleSavePatrolRoute = () => {
    if (!selectedGuard) {
      toast({
        title: "Guardia non selezionata",
        description: "Seleziona una guardia per salvare il turno",
        variant: "destructive",
      });
      return;
    }

    if (patrolRoute.length === 0) {
      toast({
        title: "Nessun sito nella sequenza",
        description: "Aggiungi almeno un sito alla sequenza di pattuglia",
        variant: "destructive",
      });
      return;
    }

    // Prepara i dati per il salvataggio
    const patrolRouteData = {
      guardId: selectedGuard.id,
      shiftDate: selectedDate,
      startTime: "08:00", // TODO: permettere all'utente di configurare
      endTime: "20:00",
      location: selectedLocation,
      status: "planned",
      stops: patrolRoute.map((site) => ({
        siteId: site.id,
      })),
    };

    savePatrolRouteMutation.mutate(patrolRouteData);
  };

  // Carica patrol route esistente quando si seleziona una guardia
  useEffect(() => {
    // Reset route quando cambia guardia o location
    setPatrolRoute([]);
    
    // Carica route esistente se c'è una guardia selezionata
    if (selectedGuardId && selectedGuardId !== "all" && existingPatrolRoutes && existingPatrolRoutes.length > 0) {
      const guardRoute = existingPatrolRoutes.find(r => r.guardId === selectedGuardId);
      if (guardRoute && guardRoute.stops && guardRoute.stops.length > 0) {
        // Ricostruisci il patrol route dai stops esistenti
        const loadedRoute = guardRoute.stops
          .sort((a: any, b: any) => a.sequenceOrder - b.sequenceOrder)
          .map((stop: any) => mobileSites?.find(s => s.id === stop.siteId))
          .filter((site: any) => site !== undefined) as MobileSite[];
        
        setPatrolRoute(loadedRoute);
        
        toast({
          title: "Turno pattuglia caricato",
          description: `${loadedRoute.length} tappe caricate per ${selectedGuard?.firstName} ${selectedGuard?.lastName}`,
        });
      }
    }
  }, [selectedGuardId, selectedLocation, existingPatrolRoutes, mobileSites]);

  return (
    <div className="h-full flex flex-col p-6 space-y-6">
      {/* Header */}
      <div className="space-y-2">
        <h1 className="text-3xl font-bold">Planning Mobile</h1>
        <p className="text-muted-foreground">
          Pianificazione ronde, ispezioni e interventi notturni per servizi mobili
        </p>
      </div>

      {/* Filtri */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <MapPin className="h-5 w-5" />
            Filtri Pianificazione
          </CardTitle>
          <CardDescription>Seleziona sede, data e guardia per iniziare</CardDescription>
        </CardHeader>
        <CardContent className="grid grid-cols-1 md:grid-cols-3 gap-4">
          <div className="space-y-2">
            <Label htmlFor="location-select">Sede*</Label>
            <Select value={selectedLocation} onValueChange={(v) => setSelectedLocation(v as Location)}>
              <SelectTrigger id="location-select" data-testid="select-mobile-location">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="roccapiemonte">Roccapiemonte</SelectItem>
                <SelectItem value="milano">Milano</SelectItem>
                <SelectItem value="roma">Roma</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-2">
            <Label htmlFor="date-select">Data*</Label>
            <Input
              id="date-select"
              type="date"
              value={selectedDate}
              onChange={(e) => setSelectedDate(e.target.value)}
              data-testid="input-mobile-date"
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="guard-select">Guardia (opzionale)</Label>
            <Select value={selectedGuardId} onValueChange={setSelectedGuardId}>
              <SelectTrigger id="guard-select" data-testid="select-mobile-guard">
                <SelectValue placeholder="Tutte le guardie" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="all">Tutte le guardie</SelectItem>
                {availableGuards?.map((guard) => (
                  <SelectItem key={guard.id} value={guard.id}>
                    {guard.firstName} {guard.lastName} - #{guard.badgeNumber} ({guard.availableHours}h disponibili)
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </CardContent>
      </Card>

      {/* Sequenza Pattuglia */}
      {selectedGuard && patrolRoute.length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <ListOrdered className="h-5 w-5" />
              Sequenza Pattuglia - {selectedGuard.firstName} {selectedGuard.lastName}
            </CardTitle>
            <CardDescription>
              {patrolRoute.length} tappe programmate per il turno del {format(parseISO(selectedDate), "dd MMMM yyyy", { locale: it })}
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-3">
            <div className="flex gap-2 flex-wrap">
              {patrolRoute.map((site, index) => (
                <div 
                  key={site.id} 
                  className="flex items-center gap-2 p-2 border rounded-lg bg-muted/20"
                  data-testid={`route-stop-${index}`}
                >
                  <Badge className="bg-green-600">
                    {index + 1}
                  </Badge>
                  <span className="text-sm font-medium">{site.name}</span>
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={() => handleRemoveFromRoute(site.id)}
                    className="h-6 w-6 p-0"
                    data-testid={`button-remove-stop-${index}`}
                  >
                    ✕
                  </Button>
                </div>
              ))}
            </div>
            <div className="flex gap-2 pt-2">
              <Button 
                onClick={handleSavePatrolRoute}
                data-testid="button-save-patrol-route"
              >
                Salva Turno Pattuglia
              </Button>
              <Button 
                variant="outline" 
                onClick={() => setPatrolRoute([])}
                data-testid="button-clear-patrol-route"
              >
                Cancella Sequenza
              </Button>
            </div>
          </CardContent>
        </Card>
      )}

      {/* Grid: Mappa + Siti */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 flex-1">
        {/* Mappa Siti */}
        <Card className="flex flex-col">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <MapPin className="h-5 w-5" />
              Mappa Siti Mobile
            </CardTitle>
            <CardDescription>
              {mobileSites?.length || 0} siti con servizi mobili in {locationLabels[selectedLocation]}
            </CardDescription>
          </CardHeader>
          <CardContent className="flex-1 p-0 overflow-hidden">
            {sitesWithCoordinates.length > 0 ? (
              <MapContainer
                key={selectedLocation}
                center={locationCenters[selectedLocation]}
                zoom={12}
                className="h-full w-full min-h-[400px]"
                data-testid="map-container"
              >
                <MapController center={mapCenter} zoom={mapZoom} />
                <TileLayer
                  attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                  url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                {sitesWithCoordinates.map((site) => {
                  const isInRoute = patrolRoute.some(s => s.id === site.id);
                  const routeIndex = patrolRoute.findIndex(s => s.id === site.id);
                  
                  return (
                    <Marker 
                      key={site.id} 
                      position={[parseFloat(site.latitude!), parseFloat(site.longitude!)]}
                      icon={isInRoute ? greenIcon : blueIcon}
                      eventHandlers={{
                        click: () => handleAddToRoute(site),
                      }}
                    >
                      <Popup>
                        <div className="space-y-2">
                          <h4 className="font-semibold text-sm">{site.name}</h4>
                          <p className="text-xs text-muted-foreground">{site.address}</p>
                          {site.serviceTypeName && (
                            <Badge variant="outline" className="text-xs">
                              {site.serviceTypeName}
                            </Badge>
                          )}
                          {isInRoute && (
                            <Badge className="text-xs bg-green-600">
                              Tappa {routeIndex + 1}
                            </Badge>
                          )}
                        </div>
                      </Popup>
                    </Marker>
                  );
                })}
              </MapContainer>
            ) : (
              <div className="h-full flex items-center justify-center bg-muted/20">
                <div className="text-center space-y-2 p-6">
                  <MapPin className="h-12 w-12 mx-auto text-muted-foreground" />
                  <p className="text-sm text-muted-foreground">
                    Nessun sito con coordinate GPS disponibile
                    <br />
                    <span className="text-xs">Aggiungi latitudine e longitudine ai siti per visualizzarli sulla mappa</span>
                  </p>
                </div>
              </div>
            )}
          </CardContent>
        </Card>

        {/* Lista Siti Mobile */}
        <Card className="flex flex-col">
          <CardHeader>
            <CardTitle className="flex items-center gap-2">
              <Clock className="h-5 w-5" />
              Siti con Servizi Mobili
            </CardTitle>
            <CardDescription>
              Ronde notturne, ispezioni, interventi programmati
            </CardDescription>
          </CardHeader>
          <CardContent className="space-y-3 overflow-y-auto">
            {sitesLoading ? (
              <p className="text-sm text-muted-foreground">Caricamento...</p>
            ) : mobileSites && mobileSites.length > 0 ? (
              mobileSites.map((site) => {
                const isInRoute = patrolRoute.some(s => s.id === site.id);
                const routeIndex = patrolRoute.findIndex(s => s.id === site.id);
                
                return (
                  <div
                    key={site.id}
                    className="p-4 border rounded-lg space-y-2"
                    data-testid={`site-card-${site.id}`}
                  >
                    <div className="flex items-start justify-between gap-2">
                      <div className="space-y-1 flex-1">
                        <h4 className="font-semibold">{site.name}</h4>
                        <p className="text-sm text-muted-foreground flex items-center gap-1">
                          <MapPin className="h-3 w-3" />
                          {site.address}
                        </p>
                      </div>
                      <Badge className={locationColors[site.location]} data-testid={`badge-location-${site.id}`}>
                        {locationLabels[site.location]}
                      </Badge>
                    </div>
                    {site.serviceTypeName && (
                      <div className="flex items-center gap-2 text-sm">
                        <Badge variant="outline" data-testid={`badge-service-${site.id}`}>
                          {site.serviceTypeName}
                        </Badge>
                        {isInRoute && (
                          <Badge className="bg-green-600">
                            Tappa {routeIndex + 1}
                          </Badge>
                        )}
                      </div>
                    )}
                    <div className="flex gap-2 pt-2">
                      <Button 
                        size="sm" 
                        variant="default" 
                        onClick={() => handleAssignGuard(site)}
                        data-testid={`button-assign-${site.id}`}
                      >
                        Assegna Guardia
                      </Button>
                      <Button 
                        size="sm" 
                        variant="outline" 
                        onClick={() => handleZoomToSite(site)}
                        data-testid={`button-zoom-${site.id}`}
                      >
                        <Navigation className="h-4 w-4" />
                      </Button>
                    </div>
                  </div>
                );
              })
            ) : (
              <div className="text-center py-8 space-y-2">
                <MapPin className="h-12 w-12 mx-auto text-muted-foreground" />
                <p className="text-sm text-muted-foreground">
                  Nessun sito con servizi mobili in {locationLabels[selectedLocation]}
                </p>
              </div>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Guardie Disponibili */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <User className="h-5 w-5" />
            Guardie Disponibili ({availableGuards?.length || 0})
          </CardTitle>
          <CardDescription>
            Guardie con ore disponibili per {format(parseISO(selectedDate), "dd MMMM yyyy", { locale: it })}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
            {guardsLoading ? (
              <p className="text-sm text-muted-foreground col-span-full">Caricamento...</p>
            ) : availableGuards && availableGuards.length > 0 ? (
              availableGuards.map((guard) => (
                <div
                  key={guard.id}
                  className="p-3 border rounded-lg space-y-2"
                  data-testid={`guard-card-${guard.id}`}
                >
                  <div className="flex items-center justify-between">
                    <div className="space-y-1">
                      <h5 className="font-semibold text-sm">
                        {guard.firstName} {guard.lastName}
                      </h5>
                      <p className="text-xs text-muted-foreground">#{guard.badgeNumber}</p>
                    </div>
                    <Badge className={locationColors[guard.location]}>
                      {locationLabels[guard.location]}
                    </Badge>
                  </div>
                  <div className="text-xs space-y-1">
                    <div className="flex justify-between">
                      <span className="text-muted-foreground">Ore settimanali:</span>
                      <span className="font-medium">{guard.weeklyHours}h / 45h</span>
                    </div>
                    <div className="flex justify-between">
                      <span className="text-muted-foreground">Disponibili:</span>
                      <span className="font-medium text-green-600">{guard.availableHours}h</span>
                    </div>
                  </div>
                </div>
              ))
            ) : (
              <p className="text-sm text-muted-foreground col-span-full text-center py-4">
                Nessuna guardia disponibile per la data selezionata
              </p>
            )}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
