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 { Activity, Brain, Database, FileText, Terminal, RefreshCw, Play, Square, RotateCw, Shield, Trash2, ListChecks, GraduationCap, Server, Clock, Timer } from "lucide-react";
import { useToast } from "@/hooks/use-toast";
import { queryClient, apiRequest } from "@/lib/queryClient";

interface ServiceStatus {
  name: string;
  status: string;
  healthy: boolean;
  details: any;
  systemdUnit: string;
  type: string;
}

interface ServicesStatusResponse {
  services: Record<string, ServiceStatus>;
}

export default function ServicesPage() {
  const { toast } = useToast();
  
  const { data: servicesStatus, isLoading, refetch } = useQuery<ServicesStatusResponse>({
    queryKey: ["/api/services/status"],
    refetchInterval: 5000,
  });

  const serviceControlMutation = useMutation({
    mutationFn: async ({ service, action }: { service: string; action: string }) => {
      return apiRequest("POST", `/api/services/${service}/${action}`);
    },
    onSuccess: (data, variables) => {
      toast({
        title: "Operazione completata",
        description: `Servizio ${variables.service}: ${variables.action} eseguito`,
      });
      setTimeout(() => {
        queryClient.invalidateQueries({ queryKey: ["/api/services/status"] });
      }, 2000);
    },
    onError: (error: any, variables) => {
      toast({
        title: "Errore operazione",
        description: error.message || `Impossibile eseguire ${variables.action} su ${variables.service}`,
        variant: "destructive",
      });
    },
  });

  const handleServiceAction = (service: string, action: string) => {
    serviceControlMutation.mutate({ service, action });
  };

  const getStatusBadge = (service: ServiceStatus, key: string) => {
    if (service.healthy) {
      return <Badge variant="default" className="bg-green-600" data-testid={`badge-status-${key}-healthy`}>Online</Badge>;
    }
    if (service.status === 'idle') {
      return <Badge variant="secondary" data-testid={`badge-status-${key}-idle`}>In Attesa</Badge>;
    }
    if (service.status === 'offline') {
      return <Badge variant="destructive" data-testid={`badge-status-${key}-offline`}>Offline</Badge>;
    }
    if (service.status === 'error') {
      return <Badge variant="destructive" data-testid={`badge-status-${key}-error`}>Errore</Badge>;
    }
    return <Badge variant="outline" data-testid={`badge-status-${key}-unknown`}>Sconosciuto</Badge>;
  };

  const getStatusIndicator = (service: ServiceStatus) => {
    if (service.healthy) {
      return <div className="h-3 w-3 rounded-full bg-green-500 shrink-0" />;
    }
    if (service.status === 'idle') {
      return <div className="h-3 w-3 rounded-full bg-yellow-500 shrink-0" />;
    }
    return <div className="h-3 w-3 rounded-full bg-red-500 shrink-0" />;
  };

  const getServiceIcon = (key: string) => {
    const icons: Record<string, any> = {
      nodeBackend: Server,
      mlBackend: Brain,
      database: Database,
      syslogParser: FileText,
      analyticsAggregator: Activity,
      autoBlock: Shield,
      cleanup: Trash2,
      listFetcher: ListChecks,
      mlTraining: GraduationCap,
    };
    const Icon = icons[key] || Activity;
    return <Icon className="h-5 w-5" />;
  };

  const controllableServices = [
    "ids-ml-backend", "ids-syslog-parser", "ids-backend",
    "ids-analytics-aggregator", "ids-auto-block", "ids-cleanup",
    "ids-list-fetcher", "ids-ml-training"
  ];

  const getLogCommand = (key: string): string | null => {
    const logs: Record<string, string> = {
      nodeBackend: "tail -f /var/log/ids/backend.log",
      mlBackend: "journalctl -u ids-ml-backend -f",
      database: "sudo journalctl -u postgresql-16 -f",
      syslogParser: "tail -f /var/log/ids/syslog_parser.log",
      analyticsAggregator: "journalctl -u ids-analytics-aggregator -f",
      autoBlock: "journalctl -u ids-auto-block -f",
      cleanup: "journalctl -u ids-cleanup -f",
      listFetcher: "journalctl -u ids-list-fetcher -f",
      mlTraining: "journalctl -u ids-ml-training -f",
    };
    return logs[key] || null;
  };

  const renderDetailRow = (label: string, value: any, variant?: "default" | "destructive" | "secondary" | "outline") => {
    if (value === undefined || value === null) return null;
    return (
      <div className="flex items-center justify-between gap-2 flex-wrap">
        <span className="text-sm text-muted-foreground">{label}:</span>
        {variant ? (
          <Badge variant={variant} className="text-xs">{String(value)}</Badge>
        ) : (
          <span className="text-sm font-mono">{String(value)}</span>
        )}
      </div>
    );
  };

  const renderServiceDetails = (key: string, service: ServiceStatus) => {
    const d = service.details;
    if (!d) return null;

    switch (key) {
      case "nodeBackend":
        return (
          <>
            {renderDetailRow("Porta", d.port)}
            {renderDetailRow("Uptime", d.uptime)}
          </>
        );
      case "mlBackend":
        return (
          <>
            {d.modelLoaded !== undefined && renderDetailRow("Modello ML", d.modelLoaded ? "Caricato" : "Non Caricato", d.modelLoaded ? "default" : "secondary")}
            {d.error && renderDetailRow("Errore", d.error, "destructive")}
          </>
        );
      case "database":
        return (
          <>
            {d.connected && renderDetailRow("Connessione", "Attiva", "default")}
            {d.error && renderDetailRow("Errore", d.error, "destructive")}
          </>
        );
      case "syslogParser":
        return (
          <>
            {d.recentLogs30min !== undefined && renderDetailRow("Log ultimi 30min", d.recentLogs30min.toLocaleString())}
            {d.lastLog && renderDetailRow("Ultimo log", typeof d.lastLog === 'string' ? d.lastLog : new Date(d.lastLog).toLocaleString('it-IT'))}
            {d.warning && renderDetailRow("Avviso", d.warning, "destructive")}
          </>
        );
      case "analyticsAggregator":
        return (
          <>
            {d.lastRun && renderDetailRow("Ultima esecuzione", new Date(d.lastRun).toLocaleString('it-IT'))}
            {d.hoursSinceLastRun && renderDetailRow("Ore dall'ultimo run", d.hoursSinceLastRun + "h", parseFloat(d.hoursSinceLastRun) < 2 ? "default" : "destructive")}
            {d.warning && renderDetailRow("Avviso", d.warning, "destructive")}
          </>
        );
      case "autoBlock":
        return (
          <>
            {renderDetailRow("Blocchi ultimi 10min", d.recentBlocks10min)}
            {renderDetailRow("Totale bloccati", d.totalBlocked)}
            {d.lastBlock && renderDetailRow("Ultimo blocco", typeof d.lastBlock === 'string' && d.lastBlock !== 'Mai' ? new Date(d.lastBlock).toLocaleString('it-IT') : d.lastBlock)}
            {renderDetailRow("Intervallo", d.interval)}
          </>
        );
      case "cleanup":
        return (
          <>
            {renderDetailRow("Detection vecchie (>48h)", d.oldDetections48h, d.oldDetections48h > 0 ? "destructive" : "default")}
            {renderDetailRow("Detection totali", d.totalDetections)}
            {renderDetailRow("Intervallo", d.interval)}
            {d.warning && renderDetailRow("Avviso", d.warning, "destructive")}
          </>
        );
      case "listFetcher":
        return (
          <>
            {renderDetailRow("Liste totali", d.totalLists)}
            {renderDetailRow("Liste attive", d.enabledLists)}
            {d.lastFetched && renderDetailRow("Ultimo fetch", typeof d.lastFetched === 'string' && d.lastFetched !== 'Mai' ? new Date(d.lastFetched).toLocaleString('it-IT') : d.lastFetched)}
            {d.hoursSinceLastFetch && renderDetailRow("Ore dall'ultimo fetch", d.hoursSinceLastFetch + "h", parseFloat(d.hoursSinceLastFetch) < 1 ? "default" : "destructive")}
            {renderDetailRow("Intervallo", d.interval)}
          </>
        );
      case "mlTraining":
        return (
          <>
            {d.lastTraining && renderDetailRow("Ultimo training", typeof d.lastTraining === 'string' && d.lastTraining !== 'Mai' ? new Date(d.lastTraining).toLocaleString('it-IT') : d.lastTraining)}
            {d.daysSinceLastTraining && renderDetailRow("Giorni dall'ultimo", d.daysSinceLastTraining, parseFloat(d.daysSinceLastTraining) < 8 ? "default" : "destructive")}
            {d.lastStatus && renderDetailRow("Stato ultimo training", d.lastStatus, d.lastStatus === 'completed' ? "default" : "destructive")}
            {d.lastModel && renderDetailRow("Modello", d.lastModel)}
            {d.recordsProcessed && renderDetailRow("Record processati", d.recordsProcessed.toLocaleString())}
            {renderDetailRow("Intervallo", d.interval)}
          </>
        );
      default:
        return d.error ? renderDetailRow("Errore", d.error, "destructive") : null;
    }
  };

  const coreServices = ["nodeBackend", "mlBackend", "database", "syslogParser"];
  const timerServices = ["autoBlock", "analyticsAggregator", "cleanup", "listFetcher", "mlTraining"];

  const renderServiceCard = (key: string, service: ServiceStatus) => {
    const isControllable = controllableServices.includes(service.systemdUnit);
    const isTimer = service.type === "timer";
    const logCmd = getLogCommand(key);

    return (
      <Card key={key} data-testid={`card-service-${key}`}>
        <CardHeader className="flex flex-row items-center justify-between gap-2 space-y-0 pb-2">
          <CardTitle className="flex items-center gap-2 text-base">
            {getServiceIcon(key)}
            <span className="truncate">{service.name}</span>
          </CardTitle>
          <div className="flex items-center gap-2 shrink-0">
            {isTimer && <Timer className="h-4 w-4 text-muted-foreground" />}
            {getStatusIndicator(service)}
          </div>
        </CardHeader>
        <CardContent className="space-y-3">
          <div className="flex items-center justify-between gap-2">
            <span className="text-sm text-muted-foreground">Stato:</span>
            {getStatusBadge(service, key)}
          </div>
          
          <div className="flex items-center justify-between gap-2">
            <span className="text-sm text-muted-foreground">Systemd:</span>
            <Badge variant="outline" className="text-xs font-mono">
              {service.systemdUnit}{isTimer ? '.timer' : '.service'}
            </Badge>
          </div>

          {renderServiceDetails(key, service)}

          {isControllable && (
            <div className="space-y-2 pt-2 border-t">
              <p className="text-xs font-medium text-muted-foreground">Controlli:</p>
              <div className="flex gap-2 flex-wrap">
                <Button
                  size="sm"
                  variant="outline"
                  onClick={() => handleServiceAction(service.systemdUnit, "restart")}
                  disabled={serviceControlMutation.isPending}
                  data-testid={`button-restart-${key}`}
                >
                  <RotateCw className="h-3 w-3 mr-1" />
                  Restart
                </Button>
                <Button
                  size="sm"
                  variant="outline"
                  onClick={() => handleServiceAction(service.systemdUnit, "start")}
                  disabled={serviceControlMutation.isPending || service.status === 'running'}
                  data-testid={`button-start-${key}`}
                >
                  <Play className="h-3 w-3 mr-1" />
                  Start
                </Button>
                <Button
                  size="sm"
                  variant="outline"
                  onClick={() => handleServiceAction(service.systemdUnit, "stop")}
                  disabled={serviceControlMutation.isPending || service.status === 'offline'}
                  data-testid={`button-stop-${key}`}
                >
                  <Square className="h-3 w-3 mr-1" />
                  Stop
                </Button>
              </div>
            </div>
          )}

          {logCmd && (
            <div className="p-2 bg-muted rounded-md">
              <p className="text-xs font-medium text-muted-foreground mb-1">Log:</p>
              <code className="text-xs font-mono break-all" data-testid={`code-log-${key}`}>{logCmd}</code>
            </div>
          )}
        </CardContent>
      </Card>
    );
  };

  return (
    <div className="flex flex-col gap-6 p-6" data-testid="page-services">
      <div className="flex items-center justify-between gap-4 flex-wrap">
        <div>
          <h1 className="text-3xl font-semibold" data-testid="text-services-title">Gestione Servizi</h1>
          <p className="text-muted-foreground" data-testid="text-services-subtitle">
            Monitoraggio e controllo di tutti i servizi IDS
          </p>
        </div>
        <Button onClick={() => refetch()} variant="outline" data-testid="button-refresh">
          <RefreshCw className="h-4 w-4 mr-2" />
          Aggiorna
        </Button>
      </div>

      {isLoading && (
        <div className="text-center py-8 text-muted-foreground">Caricamento stato servizi...</div>
      )}

      {servicesStatus && (
        <>
          <div>
            <h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
              <Server className="h-5 w-5" />
              Servizi Core
            </h2>
            <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4">
              {coreServices.map((key) => {
                const service = (servicesStatus.services as any)[key];
                return service ? renderServiceCard(key, service) : null;
              })}
            </div>
          </div>

          <div>
            <h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
              <Clock className="h-5 w-5" />
              Timer Systemd (Attivita Periodiche)
            </h2>
            <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
              {timerServices.map((key) => {
                const service = (servicesStatus.services as any)[key];
                return service ? renderServiceCard(key, service) : null;
              })}
            </div>
          </div>
        </>
      )}

      <Card data-testid="card-additional-commands">
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Terminal className="h-5 w-5" />
            Comandi Utili
          </CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div>
            <p className="text-sm font-medium mb-2">Stato di tutti i servizi IDS:</p>
            <code className="text-xs bg-muted p-2 rounded-md block font-mono" data-testid="code-all-services">
              systemctl list-units 'ids-*' --all
            </code>
          </div>
          <div>
            <p className="text-sm font-medium mb-2">Stato di tutti i timer IDS:</p>
            <code className="text-xs bg-muted p-2 rounded-md block font-mono" data-testid="code-all-timers">
              systemctl list-timers 'ids-*' --all
            </code>
          </div>
          <div>
            <p className="text-sm font-medium mb-2">Verifica log RSyslog (ricezione log MikroTik):</p>
            <code className="text-xs bg-muted p-2 rounded-md block font-mono" data-testid="code-check-rsyslog">
              tail -f /var/log/mikrotik/raw.log
            </code>
          </div>
          <div>
            <p className="text-sm font-medium mb-2">Verifica processi IDS attivi:</p>
            <code className="text-xs bg-muted p-2 rounded-md block font-mono" data-testid="code-check-processes">
              ps aux | grep -E "python.*(main|syslog_parser)" | grep -v grep
            </code>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
