import { useQuery, useMutation } from "@tanstack/react-query";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Slider } from "@/components/ui/slider";
import { AlertTriangle, Search, Shield, Globe, MapPin, Building2, ShieldPlus, ShieldCheck, Unlock, ChevronLeft, ChevronRight } from "lucide-react";
import { format } from "date-fns";
import { useState, useEffect, useMemo } from "react";
import type { Detection, Whitelist } from "@shared/schema";
import { getFlag } from "@/lib/country-flags";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";

const ITEMS_PER_PAGE = 50;

interface DetectionsResponse {
  detections: Detection[];
  total: number;
}

export default function Detections() {
  const [searchInput, setSearchInput] = useState("");
  const [debouncedSearch, setDebouncedSearch] = useState("");
  const [anomalyTypeFilter, setAnomalyTypeFilter] = useState<string>("all");
  const [minScore, setMinScore] = useState(0);
  const [maxScore, setMaxScore] = useState(100);
  const [currentPage, setCurrentPage] = useState(1);
  const { toast } = useToast();

  // Debounce search input
  useEffect(() => {
    const timer = setTimeout(() => {
      setDebouncedSearch(searchInput);
      setCurrentPage(1); // Reset to first page on search
    }, 300);
    return () => clearTimeout(timer);
  }, [searchInput]);

  // Reset page on filter change
  useEffect(() => {
    setCurrentPage(1);
  }, [anomalyTypeFilter, minScore, maxScore]);

  // Build query params with pagination and search
  const queryParams = useMemo(() => {
    const params = new URLSearchParams();
    params.set("limit", ITEMS_PER_PAGE.toString());
    params.set("offset", ((currentPage - 1) * ITEMS_PER_PAGE).toString());
    if (anomalyTypeFilter !== "all") {
      params.set("anomalyType", anomalyTypeFilter);
    }
    if (minScore > 0) {
      params.set("minScore", minScore.toString());
    }
    if (maxScore < 100) {
      params.set("maxScore", maxScore.toString());
    }
    if (debouncedSearch.trim()) {
      params.set("search", debouncedSearch.trim());
    }
    return params.toString();
  }, [currentPage, anomalyTypeFilter, minScore, maxScore, debouncedSearch]);

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

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

  const { data: whitelistData } = useQuery<{ items: Whitelist[]; total: number }>({
    queryKey: ["/api/whitelist", "all"],
    queryFn: () => fetch("/api/whitelist?limit=10000").then(r => r.json()),
  });

  const whitelistedIps = new Set(whitelistData?.items?.map(w => w.ipAddress) || []);

  // Mutation per aggiungere a whitelist
  const addToWhitelistMutation = useMutation({
    mutationFn: async (detection: Detection) => {
      return await apiRequest("POST", "/api/whitelist", {
        ipAddress: detection.sourceIp,
        reason: `Auto-added from detection: ${detection.anomalyType} (Risk: ${parseFloat(detection.riskScore).toFixed(1)})`
      });
    },
    onSuccess: (_, detection) => {
      toast({
        title: "IP aggiunto alla whitelist",
        description: `${detection.sourceIp} è stato aggiunto alla whitelist e sbloccato dai router.`,
      });
      queryClient.invalidateQueries({ queryKey: ["/api/whitelist"] });
      queryClient.invalidateQueries({ queryKey: ["/api/detections"] });
    },
    onError: (error: any, detection) => {
      toast({
        title: "Errore",
        description: error.message || `Impossibile aggiungere ${detection.sourceIp} alla whitelist.`,
        variant: "destructive",
      });
    }
  });

  // Mutation per sbloccare IP dai router
  const unblockMutation = useMutation({
    mutationFn: async (detection: Detection) => {
      return await apiRequest("POST", "/api/unblock-ip", {
        ipAddress: detection.sourceIp
      });
    },
    onSuccess: (data: any, detection) => {
      toast({
        title: "IP sbloccato",
        description: `${detection.sourceIp} è stato rimosso dalla blocklist di ${data.unblocked_from || 0} router.`,
      });
      queryClient.invalidateQueries({ queryKey: ["/api/detections"] });
    },
    onError: (error: any, detection) => {
      toast({
        title: "Errore sblocco",
        description: error.message || `Impossibile sbloccare ${detection.sourceIp} dai router.`,
        variant: "destructive",
      });
    }
  });

  const getRiskBadge = (riskScore: string) => {
    const score = parseFloat(riskScore);
    if (score >= 85) return <Badge variant="destructive">CRITICO</Badge>;
    if (score >= 70) return <Badge className="bg-orange-500">ALTO</Badge>;
    if (score >= 60) return <Badge className="bg-yellow-500">MEDIO</Badge>;
    if (score >= 40) return <Badge variant="secondary">BASSO</Badge>;
    return <Badge variant="outline">NORMALE</Badge>;
  };

  const getAnomalyTypeLabel = (type: string) => {
    const labels: Record<string, string> = {
      ddos: "DDoS Attack",
      port_scan: "Port Scanning",
      brute_force: "Brute Force",
      botnet: "Botnet Activity",
      suspicious: "Suspicious Activity"
    };
    return labels[type] || type;
  };

  return (
    <div className="flex flex-col gap-6 p-6" data-testid="page-detections">
      <div>
        <h1 className="text-3xl font-semibold" data-testid="text-page-title">Rilevamenti</h1>
        <p className="text-muted-foreground" data-testid="text-page-subtitle">
          Anomalie rilevate dal sistema IDS
        </p>
      </div>

      {/* Search and Filters */}
      <Card data-testid="card-filters">
        <CardContent className="pt-6">
          <div className="flex flex-col gap-4">
            <div className="flex items-center gap-4 flex-wrap">
              <div className="relative flex-1 min-w-[200px]">
                <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
                <Input
                  placeholder="Cerca per IP, paese, organizzazione..."
                  value={searchInput}
                  onChange={(e) => setSearchInput(e.target.value)}
                  className="pl-9"
                  data-testid="input-search"
                />
              </div>

              <Select value={anomalyTypeFilter} onValueChange={setAnomalyTypeFilter}>
                <SelectTrigger className="w-[200px]" data-testid="select-anomaly-type">
                  <SelectValue placeholder="Tipo attacco" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Tutti i tipi</SelectItem>
                  <SelectItem value="ddos">DDoS Attack</SelectItem>
                  <SelectItem value="port_scan">Port Scanning</SelectItem>
                  <SelectItem value="brute_force">Brute Force</SelectItem>
                  <SelectItem value="botnet">Botnet Activity</SelectItem>
                  <SelectItem value="suspicious">Suspicious Activity</SelectItem>
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-2">
              <div className="flex items-center justify-between text-sm">
                <span className="text-muted-foreground">Risk Score:</span>
                <span className="font-medium" data-testid="text-score-range">
                  {minScore} - {maxScore}
                </span>
              </div>
              <div className="flex items-center gap-4">
                <span className="text-xs text-muted-foreground w-8">0</span>
                <Slider
                  min={0}
                  max={100}
                  step={5}
                  value={[minScore, maxScore]}
                  onValueChange={([min, max]) => {
                    setMinScore(min);
                    setMaxScore(max);
                  }}
                  className="flex-1"
                  data-testid="slider-risk-score"
                />
                <span className="text-xs text-muted-foreground w-8">100</span>
              </div>
            </div>
          </div>
        </CardContent>
      </Card>

      {/* Detections List */}
      <Card data-testid="card-detections-list">
        <CardHeader>
          <CardTitle className="flex items-center justify-between gap-2 flex-wrap">
            <div className="flex items-center gap-2">
              <AlertTriangle className="h-5 w-5" />
              Rilevamenti ({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>
          ) : detections.length > 0 ? (
            <div className="space-y-3">
              {detections.map((detection) => (
                <div
                  key={detection.id}
                  className="p-4 rounded-lg border hover-elevate"
                  data-testid={`detection-${detection.id}`}
                >
                  <div className="flex items-start justify-between gap-4">
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-3 mb-2 flex-wrap">
                        {/* Flag Emoji */}
                        {detection.countryCode && (
                          <span className="text-2xl" title={detection.country || detection.countryCode} data-testid={`flag-${detection.id}`}>
                            {getFlag(detection.country, detection.countryCode)}
                          </span>
                        )}
                        
                        <code className="font-mono font-semibold text-lg" data-testid={`text-ip-${detection.id}`}>
                          {detection.sourceIp}
                        </code>
                        {getRiskBadge(detection.riskScore)}
                        <Badge variant="outline" data-testid={`badge-type-${detection.id}`}>
                          {getAnomalyTypeLabel(detection.anomalyType)}
                        </Badge>
                      </div>

                      <p className="text-sm text-muted-foreground mb-3" data-testid={`text-reason-${detection.id}`}>
                        {detection.reason}
                      </p>

                      {/* Geolocation Info */}
                      {(detection.country || detection.organization || detection.asNumber) && (
                        <div className="flex flex-wrap gap-3 mb-3 text-sm" data-testid={`geo-info-${detection.id}`}>
                          {detection.country && (
                            <div className="flex items-center gap-1.5 text-muted-foreground">
                              <Globe className="h-3.5 w-3.5" />
                              <span data-testid={`text-country-${detection.id}`}>
                                {detection.city ? `${detection.city}, ${detection.country}` : detection.country}
                              </span>
                            </div>
                          )}
                          {detection.organization && (
                            <div className="flex items-center gap-1.5 text-muted-foreground">
                              <Building2 className="h-3.5 w-3.5" />
                              <span data-testid={`text-org-${detection.id}`}>{detection.organization}</span>
                            </div>
                          )}
                          {detection.asNumber && (
                            <div className="flex items-center gap-1.5 text-muted-foreground">
                              <MapPin className="h-3.5 w-3.5" />
                              <span data-testid={`text-as-${detection.id}`}>
                                {detection.asNumber} {detection.asName && `- ${detection.asName}`}
                              </span>
                            </div>
                          )}
                        </div>
                      )}

                      <div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
                        <div>
                          <p className="text-muted-foreground text-xs">Risk Score</p>
                          <p className="font-medium" data-testid={`text-risk-${detection.id}`}>
                            {parseFloat(detection.riskScore).toFixed(1)}/100
                          </p>
                        </div>
                        <div>
                          <p className="text-muted-foreground text-xs">Confidence</p>
                          <p className="font-medium" data-testid={`text-confidence-${detection.id}`}>
                            {parseFloat(detection.confidence).toFixed(1)}%
                          </p>
                        </div>
                        <div>
                          <p className="text-muted-foreground text-xs">Log Count</p>
                          <p className="font-medium" data-testid={`text-logs-${detection.id}`}>
                            {detection.logCount}
                          </p>
                        </div>
                        <div>
                          <p className="text-muted-foreground text-xs">Rilevato</p>
                          <p className="font-medium" data-testid={`text-detected-${detection.id}`}>
                            {format(new Date(detection.detectedAt), "dd/MM HH:mm")}
                          </p>
                        </div>
                      </div>

                      <div className="flex items-center gap-4 mt-3 text-xs text-muted-foreground">
                        <span data-testid={`text-first-seen-${detection.id}`}>
                          Prima: {format(new Date(detection.firstSeen), "dd/MM HH:mm:ss")}
                        </span>
                        <span data-testid={`text-last-seen-${detection.id}`}>
                          Ultima: {format(new Date(detection.lastSeen), "dd/MM HH:mm:ss")}
                        </span>
                      </div>
                    </div>

                    <div className="flex flex-col items-end gap-2">
                      {detection.blocked ? (
                        <Badge variant="destructive" className="flex items-center gap-1" data-testid={`badge-blocked-${detection.id}`}>
                          <Shield className="h-3 w-3" />
                          Bloccato
                        </Badge>
                      ) : (
                        <Badge variant="outline" data-testid={`badge-active-${detection.id}`}>
                          Attivo
                        </Badge>
                      )}

                      {whitelistedIps.has(detection.sourceIp) ? (
                        <Button 
                          variant="outline" 
                          size="sm" 
                          disabled
                          className="w-full bg-green-500/10 border-green-500 text-green-600 dark:text-green-400"
                          data-testid={`button-whitelist-${detection.id}`}
                        >
                          <ShieldCheck className="h-3 w-3 mr-1" />
                          In Whitelist
                        </Button>
                      ) : (
                        <Button 
                          variant="outline" 
                          size="sm" 
                          onClick={() => addToWhitelistMutation.mutate(detection)}
                          disabled={addToWhitelistMutation.isPending}
                          className="w-full"
                          data-testid={`button-whitelist-${detection.id}`}
                        >
                          <ShieldPlus className="h-3 w-3 mr-1" />
                          Whitelist
                        </Button>
                      )}

                      {detection.blocked && (
                        <Button 
                          variant="outline" 
                          size="sm" 
                          onClick={() => unblockMutation.mutate(detection)}
                          disabled={unblockMutation.isPending}
                          className="w-full"
                          data-testid={`button-unblock-${detection.id}`}
                        >
                          <Unlock className="h-3 w-3 mr-1" />
                          Sblocca Router
                        </Button>
                      )}
                    </div>
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="text-center py-12 text-muted-foreground" data-testid="text-no-results">
              <AlertTriangle className="h-12 w-12 mx-auto mb-2 opacity-50" />
              <p>Nessun rilevamento trovato</p>
              {debouncedSearch && (
                <p className="text-sm">Prova con un altro termine di ricerca</p>
              )}
            </div>
          )}
          
          {/* Bottom pagination */}
          {totalPages > 1 && detections.length > 0 && (
            <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>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
