import { useState, useRef, useCallback, useMemo } from "react"
import { Bot, ExternalLink, Activity, Cpu, Wrench, Monitor, Shield, Check, X } from "lucide-react"
import { api } from "@/lib/api"
import { useAgentStatus, useModels, useQueryClient, qk } from "@/lib/queries"
import { useDialog } from "@/lib/useDialog"
import { cn, resolveExternalUrl } from "@/lib/utils"


function Tile({ label, ok, detail, icon: Icon, onClick }: { label: string; ok: boolean; detail?: string; icon: any; onClick?: () => void }) {
  return (
    <div 
      onClick={onClick}
      className={cn(
        "rounded-2xl border bg-card/45 backdrop-blur-md p-5 shadow-lg shadow-black/10 flex flex-col justify-between gap-3 hover:border-primary/40 transition-all duration-300",
        ok ? "border-border/60" : "border-amber-500/30",
        onClick && "cursor-pointer hover:bg-card/70"
      )}
    >
      <div className="flex items-center justify-between">
        <span className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground">{label}</span>
        <Icon className={cn("h-4.5 w-4.5", ok ? "text-primary" : "text-amber-500")} />
      </div>
      
      <div className="space-y-1.5">
        <div className="flex items-center gap-2">
          <span className={cn(
            "h-2 w-2 rounded-full ring-2 ring-black/40",
            ok ? "bg-emerald-500 animate-pulse" : "bg-amber-500"
          )} />
          <span className="text-xs font-semibold text-foreground">
            {ok ? "Bereit / Online" : "Offline / Inaktiv"}
          </span>
        </div>
        {detail && <div className="text-[10px] font-mono text-muted-foreground truncate max-w-[200px]" title={detail}>{detail}</div>}
      </div>
      {onClick && (
        <button
          onClick={(e) => {
            e.stopPropagation()
            onClick()
          }}
          className="mt-2 flex items-center justify-center gap-1.5 w-full py-1.5 px-3 rounded-lg border border-primary/30 bg-primary/10 hover:bg-primary/20 text-primary text-[10px] font-bold uppercase tracking-wider transition-all cursor-pointer font-space"
        >
          <Cpu className="h-3.5 w-3.5" />
          <span>Gehirn wechseln</span>
        </button>
      )}
    </div>
  )
}

export function AgentView() {
  const { data: s, error: sErr } = useAgentStatus(5_000)
  const { data: modelsData } = useModels()
  const { showAlert, dialogElement } = useDialog()
  const qc = useQueryClient()
  const error = sErr ? String(sErr) : ""

  const availableModels = useMemo(() => {
    const names = (modelsData?.models ?? []).map(
      (m) => m.name.split("/").pop()?.replace(".gguf", "") || m.name)
    return ["auto", "fast", "heavy", ...names]
  }, [modelsData])

  // Graph UI state
  const [hoveredNode, setHoveredNode] = useState<string | null>(null)
  const [showBrainSelect, setShowBrainSelect] = useState(false)

  // Canvas pixel tracking for pixel-perfect connection graph without non-uniform scaling
  const [dimensions, setDimensions] = useState({ width: 800, height: 360 })
  const observerRef = useRef<ResizeObserver | null>(null)

  const containerRef = useCallback((node: HTMLDivElement | null) => {
    if (observerRef.current) {
      observerRef.current.disconnect()
      observerRef.current = null
    }
    if (node) {
      const observer = new ResizeObserver((entries) => {
        if (!entries || entries.length === 0) return
        const rect = entries[0].contentRect
        setDimensions({ width: rect.width, height: rect.height })
      })
      observer.observe(node)
      observerRef.current = observer
    }
  }, [])

  const w = dimensions.width
  const h = dimensions.height

  // Helper to generate curve between any two points
  const getCurvePath = (startX: number, startY: number, endX: number, endY: number) => {
    const midX = (startX + endX) / 2
    return `M ${startX} ${startY} C ${midX} ${startY}, ${midX} ${endY}, ${endX} ${endY}`
  }

  async function changeBrainModel(model: string) {
    try {
      await api("/api/agent/brain", {
        method: "POST",
        body: JSON.stringify({ model })
      })
      showAlert("Erfolgreich", `Hermes-Gehirn wurde auf '${model}' geändert. Der Gateway-Dienst wurde neu gestartet.`)
      qc.invalidateQueries({ queryKey: qk.agentStatus })
      setShowBrainSelect(false)
    } catch (e: any) {
      showAlert("Fehler", `Fehler beim Wechseln des Gehirns: ${e.message}`)
    }
  }

  return (
    <div className="space-y-6">
      {/* Styles inside AgentView for dash flow animations */}
      <style>{`
        @keyframes flow-dash {
          to {
            stroke-dashoffset: -20;
          }
        }
        .svg-flow-path {
          stroke-dasharray: 4 6;
          animation: flow-dash 1s linear infinite;
        }
      `}</style>

      {/* Header */}
      <div className="flex flex-col sm:flex-row justify-between sm:items-center gap-4">
        <div>
          <h1 className="text-2xl font-space font-bold tracking-tight bg-gradient-to-r from-foreground via-foreground to-primary bg-clip-text text-transparent">
            Hermes Agenten-Cockpit
          </h1>
          <p className="text-sm text-muted-foreground">
            Hermes ist ein autonomer Agent, der im Hintergrund der Box läuft (Port <code>:8642</code>) und seine eigene UI besitzt.
          </p>
        </div>
        
        {s?.webui_url && (
          <a
            href={resolveExternalUrl(s.webui_url)}
            target="_blank"
            rel="noopener"
            className={cn(
              "flex h-9 px-4 items-center gap-1.5 text-xs font-semibold rounded-lg transition-all cursor-pointer shadow-md shrink-0 self-start",
              s.webui_reachable
                ? "bg-primary text-primary-foreground hover:opacity-90 shadow-primary/10"
                : "border border-border/60 text-muted-foreground bg-background/20"
            )}
          >
            <ExternalLink className="h-4 w-4" />
            <span>AnythingLLM öffnen</span>
          </a>
        )}
      </div>

      {error && (
        <div className="rounded-xl border border-red-500/20 bg-red-500/5 p-4 text-xs text-red-400 font-mono">
          Status nicht lesbar ({error}).
        </div>
      )}

      {s && (
        <div className="space-y-6">
          {/* Tile Grid */}
          <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
            <Tile 
              label="Agent Gateway" 
              ok={s.gateway_reachable} 
              detail="Port :8642 (REST API)" 
              icon={Bot} 
            />
            <Tile
              label="AnythingLLM"
              ok={s.webui_reachable}
              detail="Chat-UI (AnythingLLM)"
              icon={Activity}
            />
            <Tile 
              label="Aktives Gehirn" 
              ok={s.gateway_reachable} 
              detail={s.brain_model ? `Model: ${s.brain_model}` : "Model: auto"} 
              icon={Cpu} 
              onClick={() => setShowBrainSelect(true)}
            />
            <Tile 
              label="Verdrahtung" 
              ok={s.has_config} 
              detail={`Config: ${s.has_config ? "✓" : "—"} · Skills: ${s.has_skills ? "✓" : "—"} · Memory: ${s.has_memories ? "✓" : "—"}`} 
              icon={Wrench} 
            />
          </div>

          {/* Interactive Gateway Graph */}
          <div className="rounded-2xl border border-border/60 bg-card/45 backdrop-blur-md p-6 shadow-lg shadow-black/10 space-y-4">
            <div>
              <span className="text-xs font-bold uppercase tracking-wider text-foreground">Interactive Agent Flow Graph</span>
              <p className="text-[10px] text-muted-foreground mt-0.5 leading-relaxed">
                Visualisiert das Zusammenspiel und die Verbindungspfade zwischen den Hermes-Systemkomponenten.
              </p>
            </div>

            {/* The Graph Canvas Area */}
            <div ref={containerRef} className="relative w-full h-96 border border-border/30 rounded-xl bg-black/25 overflow-hidden flex">
              <svg className="absolute inset-0 pointer-events-none w-full h-full">
                <defs>
                  <linearGradient id="cyan-to-teal" x1="0%" y1="0%" x2="100%" y2="0%">
                    <stop offset="0%" stopColor="#06b6d4" stopOpacity="0.45" />
                    <stop offset="100%" stopColor="#0d9488" stopOpacity="0.45" />
                  </linearGradient>
                  <linearGradient id="active-glow" x1="0%" y1="0%" x2="100%" y2="0%">
                    <stop offset="0%" stopColor="#3b82f6" stopOpacity="0.8" />
                    <stop offset="100%" stopColor="#10b981" stopOpacity="0.8" />
                  </linearGradient>
                </defs>

                {/* Connection: WebUI to Gateway */}
                <path d={getCurvePath(w * 0.15, h * 0.5, w * 0.5, h * 0.5)} stroke="url(#cyan-to-teal)" strokeWidth="1.5" fill="none" />
                {(hoveredNode === "webui" || s.webui_reachable) && (
                  <path d={getCurvePath(w * 0.15, h * 0.5, w * 0.5, h * 0.5)} stroke="#06b6d4" strokeWidth="2.5" fill="none" className="svg-flow-path" />
                )}

                {/* Connection: Gateway to Gehirn */}
                <path d={getCurvePath(w * 0.5, h * 0.5, w * 0.85, h * 0.3)} stroke="url(#cyan-to-teal)" strokeWidth="1.5" fill="none" />
                {(hoveredNode === "gateway" || hoveredNode === "brain" || s.gateway_reachable) && (
                  <path d={getCurvePath(w * 0.5, h * 0.5, w * 0.85, h * 0.3)} stroke="url(#active-glow)" strokeWidth="2.5" fill="none" className="svg-flow-path" />
                )}

                {/* Connection: Gateway to Verdrahtung */}
                <path d={getCurvePath(w * 0.5, h * 0.5, w * 0.85, h * 0.7)} stroke="url(#cyan-to-teal)" strokeWidth="1.5" fill="none" />
                {(hoveredNode === "gateway" || hoveredNode === "wiring" || s.gateway_reachable) && (
                  <path d={getCurvePath(w * 0.5, h * 0.5, w * 0.85, h * 0.7)} stroke="url(#active-glow)" strokeWidth="2.5" fill="none" className="svg-flow-path" />
                )}
              </svg>

              {/* COLUMN 1: Interface */}
              <div 
                className="absolute cursor-pointer select-none z-10 w-36 h-9 -translate-y-1/2 -translate-x-1/2 rounded-xl border border-border/60 bg-card/75 backdrop-blur-md flex items-center justify-center gap-1.5 px-2.5 hover:border-primary transition-all text-[10px] font-semibold text-foreground shadow shadow-black/20"
                style={{ left: "15%", top: "50%" }}
                onMouseEnter={() => setHoveredNode("webui")}
                onMouseLeave={() => setHoveredNode(null)}
                onClick={() => s.webui_reachable && window.open(resolveExternalUrl(s.webui_url), "_blank")}
                title={s.webui_reachable ? "Klicken um AnythingLLM zu öffnen" : "AnythingLLM offline"}
              >
                <Activity className={cn("h-3.5 w-3.5", s.webui_reachable ? "text-emerald-400" : "text-amber-500")} />
                <span>AnythingLLM</span>
                <span className={cn("w-1.5 h-1.5 rounded-full animate-pulse ml-auto", s.webui_reachable ? "bg-emerald-500" : "bg-amber-500")} />
              </div>

              {/* COLUMN 2: Gateway */}
              <div 
                className="absolute select-none z-10 w-40 py-2.5 px-3 -translate-y-1/2 -translate-x-1/2 rounded-2xl border border-primary/50 bg-card/90 backdrop-blur-md flex flex-col items-center justify-center text-center shadow-lg shadow-primary/5 cursor-pointer"
                style={{ left: "50%", top: "50%" }}
                onMouseEnter={() => setHoveredNode("gateway")}
                onMouseLeave={() => setHoveredNode(null)}
              >
                <div className="flex items-center gap-1">
                  <Bot className="h-3.5 w-3.5 text-primary" />
                  <span className="text-[10px] uppercase font-bold text-primary font-space tracking-wide">Agent Gateway</span>
                </div>
                <div className="text-[9px] font-mono text-muted-foreground mt-0.5">Port :8642</div>
                <div className={cn("mt-1 px-1.5 py-0.5 rounded text-[8px] font-semibold uppercase font-mono border", 
                  s.gateway_reachable 
                    ? "bg-emerald-500/10 border-emerald-500/20 text-emerald-400" 
                    : "bg-red-500/10 border-red-500/20 text-red-400"
                )}>
                  {s.gateway_reachable ? "Online" : "Offline"}
                </div>
              </div>

              {/* COLUMN 3: Brain & Wiring */}
              <div 
                className={cn(
                  "absolute z-20 w-44 py-1.5 px-3 -translate-y-1/2 -translate-x-1/2 rounded-xl border flex flex-col justify-center hover:border-primary/50 transition-all text-left shadow select-none cursor-pointer",
                  s.gateway_reachable ? "border-emerald-500/50 bg-emerald-500/5 shadow-emerald-500/5" : "border-border/60 bg-card/75"
                )}
                style={{ left: "85%", top: "30%" }}
                onMouseEnter={() => setHoveredNode("brain")}
                onMouseLeave={() => setHoveredNode(null)}
                onClick={() => setShowBrainSelect(true)}
              >
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-1 text-muted-foreground">
                    <Cpu className="h-3 w-3 text-primary" />
                    <span className="text-[10px] font-bold uppercase tracking-wider">Aktives Gehirn</span>
                  </div>
                  {s.gateway_reachable && <span className="h-1.5 w-1.5 rounded-full bg-emerald-400 animate-pulse" />}
                </div>
                <div className="text-[10px] font-mono font-medium truncate mt-0.5 text-foreground font-space" title={s.brain_model}>
                  {s.brain_model || "auto"}
                </div>
              </div>

              <div 
                className={cn(
                  "absolute z-10 w-44 py-1.5 px-3 -translate-y-1/2 -translate-x-1/2 rounded-xl border flex flex-col justify-center hover:border-primary/50 transition-all text-left shadow select-none",
                  s.has_config ? "border-emerald-500/50 bg-emerald-500/5 shadow-emerald-500/5" : "border-border/60 bg-card/75"
                )}
                style={{ left: "85%", top: "70%" }}
                onMouseEnter={() => setHoveredNode("wiring")}
                onMouseLeave={() => setHoveredNode(null)}
              >
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-1 text-muted-foreground">
                    <Wrench className="h-3 w-3 text-primary" />
                    <span className="text-[10px] font-bold uppercase tracking-wider">Verdrahtung</span>
                  </div>
                  {s.has_config && <span className="h-1.5 w-1.5 rounded-full bg-emerald-400 animate-pulse" />}
                </div>
                <div className="text-[9px] font-mono mt-0.5 text-muted-foreground flex gap-1 justify-between">
                  <span>Config: {s.has_config ? "✓" : "—"}</span>
                  <span>Skills: {s.has_skills ? "✓" : "—"}</span>
                  <span>Memory: {s.has_memories ? "✓" : "—"}</span>
                </div>
              </div>
            </div>
            
            {/* Legend */}
            <div className="flex flex-wrap items-center gap-6 mt-3 text-[10px] text-muted-foreground border-t border-border/20 pt-3">
              <span className="flex items-center gap-1.5">
                <span className="h-2 w-2 rounded-full bg-cyan-400" />
                <span>Cyan-Fluss: Client-Anfrage an Agenten</span>
              </span>
              <span className="flex items-center gap-1.5">
                <span className="h-2 w-2 rounded-full bg-emerald-500 animate-pulse" />
                <span>Grüner Puls: Verbindung hergestellt / Modul online</span>
              </span>
            </div>
          </div>

          {/* PC Executor Status Card */}
          <div className="rounded-2xl border border-border/60 bg-card/45 backdrop-blur-md p-6 space-y-4 shadow-lg shadow-black/10">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-2">
                <Monitor className="h-5 w-5 text-primary" />
                <h3 className="text-sm font-bold uppercase tracking-wider text-foreground">PC Verbindung</h3>
              </div>
              <div className="flex items-center gap-2">
                <span className={cn("h-2 w-2 rounded-full", s.pc_executor_reachable ? "bg-emerald-500 animate-pulse" : "bg-amber-500")} />
                <span className="text-xs font-semibold text-foreground">
                  {s.pc_executor_reachable ? "Erreichbar" : "Nicht verbunden"}
                </span>
              </div>
            </div>

            <div className="grid gap-6 md:grid-cols-2 text-xs text-muted-foreground leading-relaxed text-left">
              <div className="space-y-3">
                <p>
                  Der <strong className="text-foreground">Hermes PC Executor</strong> läuft auf <code className="text-foreground font-mono px-1 py-0.5 rounded bg-muted/40 border border-border/30">192.168.178.98:7777</code> und ermöglicht Hermes den direkten Zugriff auf deinen Windows-PC — Shell-Befehle, Screenshots, Tastatureingaben.
                </p>
                <p>
                  Hermes erreicht den PC über den MCP-Server <code className="text-foreground font-mono px-1 py-0.5 rounded bg-muted/40 border border-border/30">hermes-pc-control</code>, der automatisch beim Gateway-Start verbunden wird.
                </p>
              </div>

              <div className="space-y-3">
                {s.pc_executor_reachable ? (
                  <div className="p-3.5 bg-emerald-500/5 border border-emerald-500/20 rounded-xl space-y-1">
                    <div className="text-emerald-400 font-semibold text-xs flex items-center gap-1.5">
                      <span className="h-1.5 w-1.5 rounded-full bg-emerald-500 animate-pulse" />
                      PC Executor verbunden
                    </div>
                    <p className="text-[10px]">
                      Hermes kann jetzt per Telegram oder WebUI Befehle auf TobisNicerPC ausführen. Nutze <code className="text-foreground">pc_shell</code>, <code className="text-foreground">pc_screenshot</code> oder <code className="text-foreground">pc_open</code>.
                    </p>
                  </div>
                ) : (
                  <div className="space-y-2">
                    <h4 className="text-xs font-bold text-foreground">PC Executor starten</h4>
                    <p>Starte <code className="text-foreground font-mono">start.bat</code> im Ordner <code className="text-foreground font-mono">client\hermes-pc\</code> auf dem Windows-PC und lasse das Fenster offen.</p>
                    <div className="p-3 bg-background/25 rounded-xl border border-border/30 font-mono text-[9px] text-cyan-300">
                      client\hermes-pc\start.bat
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>

          {/* Diagnostic Details if Offline */}
          {!s.gateway_reachable && (
            <div className="rounded-2xl border border-border/60 bg-card/45 backdrop-blur-md p-6 space-y-4 shadow-lg shadow-black/10 text-left">
              <div className="flex items-center gap-2">
                <Shield className="h-5 w-5 text-amber-500" />
                <h3 className="text-sm font-bold uppercase tracking-wider text-foreground">Hermes-Agent Diagnostics</h3>
              </div>
              
              <div className="text-xs text-muted-foreground space-y-3 leading-relaxed">
                <p>
                  Der Hermes-Dienst ist auf der Box derzeit offline oder kann sich nicht mit dem lokalen llama-swap verbinden.
                </p>
                <p>
                  Stelle sicher, dass die systemd-Dienste auf der Box laufen. Du kannst den Status im <strong>OS &amp; Updates Drawer</strong> prüfen und die Dienste bei Bedarf neu starten.
                </p>
                
                <div className="p-3.5 bg-background/25 rounded-xl border border-border/30 font-mono text-[10px] space-y-1">
                  <div className="text-muted-foreground/60"># Dienste manuell auf der Box prüfen:</div>
                  <div className="text-primary">systemctl --user status hermes-gateway</div>
                  <div className="text-primary">systemctl --user status hermes-webui</div>
                </div>

                <p>
                  Weitere Einrichtungsdetails (Brain-Konfiguration, MCP-Kopplungen, SSH-Tunneling und Such-Engines) findest du in der Dokumentationsdatei:
                  <code className="ml-1 px-1.5 py-0.5 rounded bg-muted/40 text-foreground border border-border/30">docs/HERMES_SETUP.md</code>.
                </p>
              </div>
            </div>
          )}
        </div>
      )}

      {/* Brain Selection Modal */}
      {s && showBrainSelect && (
        <div className="fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-center justify-center p-4">
          <div className="w-full max-w-md rounded-2xl border border-border/80 bg-card p-6 shadow-2xl space-y-4 animate-in fade-in zoom-in-95 duration-200">
            <div className="flex items-center justify-between border-b border-border/20 pb-2">
              <h3 className="text-xs font-bold uppercase tracking-wider text-primary flex items-center gap-1.5">
                <Cpu className="h-4 w-4" />
                <span>Hermes-Gehirn konfigurieren</span>
              </h3>
              <button 
                onClick={() => setShowBrainSelect(false)}
                className="p-1 rounded hover:bg-accent text-muted-foreground hover:text-foreground cursor-pointer"
              >
                <X className="h-4 w-4" />
              </button>
            </div>
            <p className="text-xs text-muted-foreground leading-relaxed">
              Das „Gehirn" ist das primäre LLM für Hermes. Wähle ein Modell aus deiner Bibliothek oder nutze ein Gateway-Alias (<code className="text-primary font-semibold">auto</code> / <code className="text-primary font-semibold">fast</code> / <code className="text-primary font-semibold">heavy</code>):
            </p>
            
            <div className="space-y-1.5 max-h-60 overflow-y-auto pr-1">
              {availableModels.map((m) => {
                const isAlias = ["auto", "fast", "heavy"].includes(m);
                return (
                  <button
                    key={m}
                    onClick={() => changeBrainModel(m)}
                    className={cn(
                      "w-full text-left px-3 py-2.5 rounded-lg text-xs hover:bg-accent flex items-center justify-between font-mono cursor-pointer border border-border/30",
                      s.brain_model === m || (!s.brain_model && m === "auto")
                        ? "text-primary font-bold bg-primary/10 border-primary/30" 
                        : "text-foreground bg-background/20"
                    )}
                  >
                    <div className="flex flex-col text-left">
                      <span className="font-semibold truncate max-w-[280px]">
                        {m}
                      </span>
                      <span className="text-[9px] text-muted-foreground mt-0.5">
                        {isAlias ? "Gateway Routing Alias" : "Installiertes GGUF Modell"}
                      </span>
                    </div>
                    {(s.brain_model === m || (!s.brain_model && m === "auto")) && (
                      <Check className="h-4 w-4 shrink-0 text-primary" />
                    )}
                  </button>
                );
              })}
            </div>
          </div>
        </div>
      )}

      {dialogElement}
    </div>
  )
}
