import { useQuery, useMutation } from "@tanstack/react-query";
import { queryClient, apiRequest } from "@/lib/queryClient";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Shield, Plus, Trash2, CheckCircle2, XCircle, Search, ChevronLeft, ChevronRight } from "lucide-react";
import { format } from "date-fns";
import { useState, useEffect, useMemo } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import type { Whitelist } from "@shared/schema";
import { insertWhitelistSchema } from "@shared/schema";
import { useToast } from "@/hooks/use-toast";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
  DialogFooter,
} from "@/components/ui/dialog";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";

const ITEMS_PER_PAGE = 50;

const whitelistFormSchema = insertWhitelistSchema.extend({
  ipAddress: z.string()
    .min(7, "Inserisci un IP valido")
    .regex(/^(\d{1,3}\.){3}\d{1,3}$/, "Formato IP non valido")
    .refine((ip) => {
      const parts = ip.split('.').map(Number);
      return parts.every(part => part >= 0 && part <= 255);
    }, "Ogni ottetto deve essere tra 0 e 255"),
});

interface WhitelistResponse {
  items: Whitelist[];
  total: number;
}

export default function WhitelistPage() {
  const { toast } = useToast();
  const [isAddDialogOpen, setIsAddDialogOpen] = useState(false);
  const [searchInput, setSearchInput] = useState("");
  const [debouncedSearch, setDebouncedSearch] = useState("");
  const [currentPage, setCurrentPage] = useState(1);

  const form = useForm<z.infer<typeof whitelistFormSchema>>({
    resolver: zodResolver(whitelistFormSchema),
    defaultValues: {
      ipAddress: "",
      comment: "",
      reason: "",
      active: true,
    },
  });

  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedSearch(searchInput);
      setCurrentPage(1);
    }, 300);
    return () => clearTimeout(timer);
  }, [searchInput]);

  const queryParams = useMemo(() => {
    const params = new URLSearchParams();
    params.set("limit", ITEMS_PER_PAGE.toString());
    params.set("offset", ((currentPage - 1) * ITEMS_PER_PAGE).toString());
    if (debouncedSearch.trim()) {
      params.set("search", debouncedSearch.trim());
    }
    return params.toString();
  }, [currentPage, debouncedSearch]);

  const { data, isLoading } = useQuery<WhitelistResponse>({
    queryKey: ["/api/whitelist", currentPage, debouncedSearch],
    queryFn: () => fetch(`/api/whitelist?${queryParams}`).then(r => r.json()),
    refetchInterval: 10000,
  });

  const whitelistItems = data?.items || [];
  const totalCount = data?.total || 0;
  const totalPages = Math.ceil(totalCount / ITEMS_PER_PAGE);

  const addMutation = useMutation({
    mutationFn: async (data: z.infer<typeof whitelistFormSchema>) => {
      return await apiRequest("POST", "/api/whitelist", data);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/whitelist"] });
      toast({
        title: "IP aggiunto",
        description: "L'indirizzo IP è stato aggiunto alla whitelist",
      });
      setIsAddDialogOpen(false);
      form.reset();
    },
    onError: (error: any) => {
      toast({
        title: "Errore",
        description: error.message || "Impossibile aggiungere l'IP alla whitelist",
        variant: "destructive",
      });
    },
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      await apiRequest("DELETE", `/api/whitelist/${id}`);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["/api/whitelist"] });
      toast({
        title: "IP rimosso",
        description: "L'indirizzo IP è stato rimosso dalla whitelist",
      });
    },
    onError: (error: any) => {
      toast({
        title: "Errore",
        description: error.message || "Impossibile rimuovere l'IP dalla whitelist",
        variant: "destructive",
      });
    },
  });

  const onSubmit = (data: z.infer<typeof whitelistFormSchema>) => {
    addMutation.mutate(data);
  };

  return (
    <div className="flex flex-col gap-6 p-6" data-testid="page-whitelist">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-semibold" data-testid="text-page-title">Whitelist IP</h1>
          <p className="text-muted-foreground" data-testid="text-page-subtitle">
            Gestisci gli indirizzi IP fidati che non verranno bloccati
          </p>
        </div>

        <Dialog open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen}>
          <DialogTrigger asChild>
            <Button data-testid="button-add-whitelist">
              <Plus className="h-4 w-4 mr-2" />
              Aggiungi IP
            </Button>
          </DialogTrigger>
          <DialogContent data-testid="dialog-add-whitelist">
            <DialogHeader>
              <DialogTitle>Aggiungi IP alla Whitelist</DialogTitle>
              <DialogDescription>
                Inserisci l'indirizzo IP che vuoi proteggere dal blocco automatico
              </DialogDescription>
            </DialogHeader>
            <Form {...form}>
              <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4 py-4">
                <FormField
                  control={form.control}
                  name="ipAddress"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Indirizzo IP *</FormLabel>
                      <FormControl>
                        <Input placeholder="192.168.1.100" {...field} data-testid="input-ip" />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
                <FormField
                  control={form.control}
                  name="reason"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Motivo</FormLabel>
                      <FormControl>
                        <Input placeholder="Es: Server backup" {...field} data-testid="input-reason" />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
                <FormField
                  control={form.control}
                  name="comment"
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Note</FormLabel>
                      <FormControl>
                        <Textarea placeholder="Note aggiuntive..." {...field} data-testid="input-comment" />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
                <DialogFooter>
                  <Button 
                    type="button" 
                    variant="outline" 
                    onClick={() => setIsAddDialogOpen(false)} 
                    data-testid="button-cancel"
                  >
                    Annulla
                  </Button>
                  <Button type="submit" disabled={addMutation.isPending} data-testid="button-confirm-add">
                    {addMutation.isPending ? "Aggiunta..." : "Aggiungi"}
                  </Button>
                </DialogFooter>
              </form>
            </Form>
          </DialogContent>
        </Dialog>
      </div>

      {/* Search Bar */}
      <Card data-testid="card-search">
        <CardContent className="pt-6">
          <div className="relative">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              placeholder="Cerca per IP, motivo, note o sorgente..."
              value={searchInput}
              onChange={(e) => setSearchInput(e.target.value)}
              className="pl-9"
              data-testid="input-search-whitelist"
            />
          </div>
        </CardContent>
      </Card>

      <Card data-testid="card-whitelist">
        <CardHeader>
          <CardTitle className="flex items-center justify-between gap-2 flex-wrap">
            <div className="flex items-center gap-2">
              <Shield className="h-5 w-5" />
              IP Protetti ({totalCount})
            </div>
            {totalPages > 1 && (
              <div className="flex items-center gap-2 text-sm font-normal">
                <Button 
                  variant="outline" 
                  size="icon"
                  onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
                  disabled={currentPage === 1}
                  data-testid="button-prev-page"
                >
                  <ChevronLeft className="h-4 w-4" />
                </Button>
                <span data-testid="text-pagination">
                  Pagina {currentPage} di {totalPages}
                </span>
                <Button 
                  variant="outline" 
                  size="icon"
                  onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
                  disabled={currentPage === totalPages}
                  data-testid="button-next-page"
                >
                  <ChevronRight className="h-4 w-4" />
                </Button>
              </div>
            )}
          </CardTitle>
        </CardHeader>
        <CardContent>
          {isLoading ? (
            <div className="text-center py-8 text-muted-foreground" data-testid="text-loading">
              Caricamento...
            </div>
          ) : whitelistItems.length > 0 ? (
            <div className="space-y-3">
              {whitelistItems.map((item) => (
                <div
                  key={item.id}
                  className="p-4 rounded-lg border hover-elevate"
                  data-testid={`whitelist-item-${item.id}`}
                >
                  <div className="flex items-start justify-between gap-4">
                    <div className="flex-1 space-y-1">
                      <div className="flex items-center gap-2">
                        <p className="font-mono font-medium" data-testid={`text-ip-${item.id}`}>
                          {item.ipAddress}
                        </p>
                        {item.active ? (
                          <CheckCircle2 className="h-4 w-4 text-green-500" data-testid={`icon-active-${item.id}`} />
                        ) : (
                          <XCircle className="h-4 w-4 text-muted-foreground" data-testid={`icon-inactive-${item.id}`} />
                        )}
                      </div>
                      {item.reason && (
                        <p className="text-sm text-muted-foreground" data-testid={`text-reason-${item.id}`}>
                          <span className="font-medium">Motivo:</span> {item.reason}
                        </p>
                      )}
                      {item.comment && (
                        <p className="text-sm text-muted-foreground" data-testid={`text-comment-${item.id}`}>
                          {item.comment}
                        </p>
                      )}
                      <p className="text-xs text-muted-foreground" data-testid={`text-created-${item.id}`}>
                        Aggiunto il {format(new Date(item.createdAt), "dd/MM/yyyy HH:mm")}
                        {item.createdBy && ` da ${item.createdBy}`}
                      </p>
                    </div>
                    <Button
                      variant="ghost"
                      size="icon"
                      onClick={() => deleteMutation.mutate(item.id)}
                      disabled={deleteMutation.isPending}
                      data-testid={`button-delete-${item.id}`}
                    >
                      <Trash2 className="h-4 w-4 text-destructive" />
                    </Button>
                  </div>
                </div>
              ))}

              {/* Bottom pagination */}
              {totalPages > 1 && (
                <div className="flex items-center justify-center gap-4 mt-6 pt-4 border-t">
                  <Button 
                    variant="outline" 
                    size="sm"
                    onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
                    disabled={currentPage === 1}
                    data-testid="button-prev-page-bottom"
                  >
                    <ChevronLeft className="h-4 w-4 mr-1" />
                    Precedente
                  </Button>
                  <span className="text-sm text-muted-foreground" data-testid="text-pagination-bottom">
                    Pagina {currentPage} di {totalPages} ({totalCount} totali)
                  </span>
                  <Button 
                    variant="outline" 
                    size="sm"
                    onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
                    disabled={currentPage === totalPages}
                    data-testid="button-next-page-bottom"
                  >
                    Successiva
                    <ChevronRight className="h-4 w-4 ml-1" />
                  </Button>
                </div>
              )}
            </div>
          ) : (
            <div className="text-center py-12 text-muted-foreground" data-testid="text-empty">
              <Shield className="h-12 w-12 mx-auto mb-4 opacity-50" />
              <p className="font-medium">Nessun IP in whitelist</p>
              {debouncedSearch ? (
                <p className="text-sm mt-2">Prova con un altro termine di ricerca</p>
              ) : (
                <p className="text-sm mt-2">Aggiungi indirizzi IP fidati per proteggerli dal blocco automatico</p>
              )}
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
