import { useEffect, useState, useRef } from "react"
import { X, RefreshCw, Terminal, Cpu, Server, Shield, Power, Eye, EyeOff, Key, AlertTriangle, Camera, Bot, Box, FileText, Package, GitCommit, ExternalLink, ArrowRight, Shuffle } from "lucide-react"
import { api, type Job, type UpdatesResp, type ServicesResp, type UpdateDetails } from "@/lib/api"
import { cn } from "@/lib/utils"
import { CustomDialog } from "./CustomDialog"


interface SystemDrawerProps {
  open: boolean
  onClose: () => void
  defaultTab?: "maintenance" | "logs" | "settings"
}

// systemd-Units (restart/logs) + reach = Stichwort zum Mappen auf /api/system/services.
const SERVICES = [
  { id: "mission-control-2", label: "Mission Control", type: "user", reach: "gateway (integr" },
  { id: "hermes-gateway", label: "Hermes Gateway", type: "user", reach: "hermes-gateway" },
  { id: "mem0-service", label: "Mem0 (Gedächtnis)", type: "user", reach: "mem0" },
  { id: "hermes-terminal", label: "Hermes Terminal", type: "user", reach: "hermes-terminal" },
  { id: "llama-swap", label: "Llama Swap", type: "system", reach: "llama-swap" },
]

function UpdateRow({ icon: Icon, iconClass, name, status, available, busy, actionLabel, onAction }: {
  icon: any; iconClass: string; name: string; status: string; available: boolean; busy?: boolean; actionLabel: string; onAction: () => void
}) {
  return (
    <div className={cn("flex items-center gap-3 rounded-lg border px-3 py-2",
      available ? "border-amber-500/30 bg-amber-500/5" : "border-border/50 bg-background/20")}>
      <Icon className={cn("h-4 w-4 shrink-0", iconClass)} />
      <div className="flex-1 min-w-0">
        <div className="text-xs text-foreground truncate">{name}</div>
        <div className={cn("text-[10px] truncate", available ? "text-amber-400/90" : "text-muted-foreground")}>{status}</div>
      </div>
      <button onClick={onAction} disabled={!available || busy}
        className={cn("text-[11px] font-semibold rounded-lg px-2.5 py-1 transition-colors shrink-0",
          available ? "bg-primary text-primary-foreground hover:opacity-90 cursor-pointer" : "border border-border/50 text-muted-foreground/40 cursor-default")}>
        {busy ? "…" : actionLabel}
      </button>
    </div>
  )
}

function ServiceRow({ label, ok, system, busy, onRestart, onLogs }: {
  label: string; ok?: boolean; system?: boolean; busy?: boolean; onRestart: () => void; onLogs: () => void
}) {
  return (
    <div className="flex items-center gap-2.5 rounded-lg border border-border/50 bg-background/20 px-3 py-2">
      <span className={cn("w-1.5 h-1.5 rounded-full shrink-0",
        ok === true ? "bg-emerald-500" : ok === false ? "bg-red-500" : "bg-muted-foreground/40")} />
      <span className="flex-1 text-xs text-foreground truncate">{label}{system && <span className="text-[9px] text-muted-foreground"> (root)</span>}</span>
      <button onClick={onRestart} disabled={busy} title="Neu starten" className="text-muted-foreground hover:text-primary transition-colors disabled:opacity-50">
        <RefreshCw className={cn("h-3.5 w-3.5", busy && "animate-spin")} />
      </button>
      <button onClick={onLogs} title="Logs ansehen" className="text-muted-foreground hover:text-primary transition-colors">
        <FileText className="h-3.5 w-3.5" />
      </button>
    </div>
  )
}

function formatBytes(bytes?: number) {
  if (bytes == null) return ""
  if (bytes > 1024 ** 3) return `${(bytes / 1024 ** 3).toFixed(2)} GB`
  return `${(bytes / 1024 ** 2).toFixed(1)} MB`
}

export function SystemDrawer({ open, onClose, defaultTab = "maintenance" }: SystemDrawerProps) {
  const [updates, setUpdates] = useState<UpdatesResp | null>(null)
  const [jobs, setJobs] = useState<Job[]>([])
  const [selectedService, setSelectedService] = useState("llama-swap")
  const [logs, setLogs] = useState("")
  const [loadingLogs, setLoadingLogs] = useState(false)
  const [logStatus, setLogStatus] = useState<string | null>(null)
  const [restartingServices, setRestartingServices] = useState<Record<string, boolean>>({})
  const [activeTab, setActiveTab] = useState<"maintenance" | "logs" | "settings">("maintenance")
  const [checkingUpdates, setCheckingUpdates] = useState(false)
  const [backupMsg, setBackupMsg] = useState("")
  const [backupRunning, setBackupRunning] = useState(false)
  const [services, setServices] = useState<ServicesResp | null>(null)
  const [backups, setBackups] = useState<{ snapshot: string; size_mb?: number }[]>([])
  const [hermesUpdating, setHermesUpdating] = useState(false)

  // Update-Detail-Fenster: zeigt VOR dem Anwenden, was genau aktualisiert wird.
  const [detail, setDetail] = useState<{ kind: "os" | "engine" | "swap" | "hermes"; loading: boolean; data: UpdateDetails | null } | null>(null)

  // Custom Dialog State
  const [dialog, setDialog] = useState<{
    type: "alert" | "confirm"
    title: string
    message: string
    onConfirm: () => void
    onCancel?: () => void
  } | null>(null)

  function showAlert(title: string, message: string, onConfirm?: () => void) {
    setDialog({
      type: "alert",
      title,
      message,
      onConfirm: () => {
        setDialog(null)
        if (onConfirm) onConfirm()
      }
    })
  }

  function showConfirm(title: string, message: string, onConfirm: () => void) {
    setDialog({
      type: "confirm",
      title,
      message,
      onConfirm: () => {
        setDialog(null)
        onConfirm()
      },
      onCancel: () => setDialog(null)
    })
  }

  function formatLastCheck(ts?: number | null) {
    if (!ts) return "Nie"
    return new Date(ts * 1000).toLocaleString("de-DE", {
      day: "2-digit",
      month: "2-digit",
      hour: "2-digit",
      minute: "2-digit",
      second: "2-digit"
    })
  }

  // Credentials State
  const [sudoPasswordInput, setSudoPasswordInput] = useState("")
  const [hfTokenInput, setHfTokenInput] = useState("")
  const [showSudo, setShowSudo] = useState(false)
  const [showHf, setShowHf] = useState(false)

  useEffect(() => {
    if (open) {
      setSudoPasswordInput(localStorage.getItem("mc_sudo_password") || "")
      setHfTokenInput(localStorage.getItem("mc_hf_token") || "")
    }
  }, [open])

  useEffect(() => {
    if (open && defaultTab) {
      setActiveTab(defaultTab)
    }
  }, [open, defaultTab])
  
  const logContainerRef = useRef<HTMLPreElement | null>(null)

  function loadUpdates() {
    api<UpdatesResp>("/api/maintenance/updates")
      .then(setUpdates)
      .catch((e) => console.error("Error loading updates", e))
  }

  function loadJobs() {
    api<{ jobs: Job[] }>("/api/jobs")
      .then((data) => setJobs(data.jobs || []))
      .catch((e) => console.error("Error loading jobs", e))
  }

  function loadServices() {
    api<ServicesResp>("/api/system/services").then(setServices).catch(() => {})
  }

  function loadBackups() {
    api<{ backups: { snapshot: string; size_mb?: number }[] }>("/api/system/backups")
      .then((d) => setBackups(d.backups || [])).catch(() => {})
  }

  function loadServiceLogs(service: string) {
    setLoadingLogs(true)
    setLogStatus(null)
    api<{ ok: boolean; text: string; err?: string; status?: string }>(`/api/maintenance/logs?service=${service}&lines=150`)
      .then((res) => {
        if (res.ok) {
          setLogs(res.text)
        } else {
          setLogs(`Fehler beim Laden der Logs: ${res.err || "Unbekannter Fehler"}`)
          if (res.status === "incorrect_password" || res.status === "password_required") {
            setLogStatus(res.status)
          }
        }
      })
      .catch((e) => setLogs(`Fehler: ${e.message}`))
      .finally(() => {
        setLoadingLogs(false)
        // Scroll to bottom
        setTimeout(() => {
          if (logContainerRef.current) {
            logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight
          }
        }, 50)
      })
  }

  // Poll jobs & updates when open
  useEffect(() => {
    if (!open) return
    loadUpdates()
    loadJobs()
    loadServices()
    loadBackups()
    const timer = setInterval(() => {
      loadJobs()
      loadUpdates()
      loadServices()
    }, 3000)
    return () => clearInterval(timer)
  }, [open])

  // Load logs when tab is active or service changes
  useEffect(() => {
    if (!open || activeTab !== "logs") return
    loadServiceLogs(selectedService)
  }, [open, activeTab, selectedService])

  // Backend-Wartungsriegel: lehnt ein zweites Update ab, solange eines läuft.
  function handledBusy(res: any): boolean {
    if (res?.status === "busy") {
      showAlert("Update läuft bereits", `Es läuft gerade „${res.running}". Bitte warte, bis es fertig ist.`)
      loadJobs()
      return true
    }
    return false
  }

  async function triggerOsUpdate() {
    try {
      const res = await api<any>("/api/maintenance/os-update", { method: "POST" })
      if (handledBusy(res)) return
      loadJobs()
      setActiveTab("maintenance")
    } catch (e: any) {
      showAlert("Fehler", `Fehler beim Starten des OS-Updates: ${e.message}`)
    }
  }

  async function triggerEngineUpdate() {
    try {
      const res = await api<any>("/api/maintenance/engine-update", { method: "POST" })
      if (handledBusy(res)) return
      loadJobs()
      setActiveTab("maintenance")
    } catch (e: any) {
      showAlert("Fehler", `Fehler beim Engine-Update: ${e.message}`)
    }
  }

  async function triggerSwapUpdate() {
    try {
      const res = await api<any>("/api/maintenance/swap-update", { method: "POST" })
      if (handledBusy(res)) return
      loadJobs()
      setActiveTab("maintenance")
    } catch (e: any) {
      showAlert("Fehler", `Fehler beim Router-Update: ${e.message}`)
    }
  }

  async function doHermesUpdate() {
    setHermesUpdating(true)
    try {
      const res = await api<any>("/api/maintenance/hermes-update", { method: "POST" })
      if (handledBusy(res)) return
      loadJobs()
    } catch (e: any) {
      showAlert("Fehler", `Hermes-Update fehlgeschlagen: ${e.message}`)
    } finally {
      setHermesUpdating(false)
    }
  }

  // Öffnet das Detail-Fenster und lädt, was genau aktualisiert würde.
  async function openUpdateDetails(kind: "os" | "engine" | "swap" | "hermes") {
    setDetail({ kind, loading: true, data: null })
    try {
      const d = await api<UpdateDetails>(`/api/maintenance/update-details?kind=${kind}`)
      setDetail({ kind, loading: false, data: d })
    } catch (e: any) {
      setDetail({ kind, loading: false, data: { kind, error: e.message } })
    }
  }

  // Bestätigung aus dem Detail-Fenster → startet das passende Update.
  function applyFromDetail() {
    const kind = detail?.kind
    setDetail(null)
    if (kind === "os") triggerOsUpdate()
    else if (kind === "engine") triggerEngineUpdate()
    else if (kind === "swap") triggerSwapUpdate()
    else if (kind === "hermes") doHermesUpdate()
  }

  async function triggerCheckUpdates() {
    setCheckingUpdates(true)
    try {
      await api("/api/maintenance/check-updates", { method: "POST" })
      loadJobs()
      setActiveTab("maintenance")
    } catch (e: any) {
      showAlert("Fehler", `Fehler bei der Update-Suche: ${e.message}`)
    } finally {
      setCheckingUpdates(false)
    }
  }

  async function triggerModelUpgrade(repo: string, role: string) {
    try {
      await api("/api/models/install", {
        method: "POST",
        body: JSON.stringify({ repo, role })
      })
      showAlert("Gestartet", `Modell-Upgrade für '${role}' (${repo}) gestartet.`)
      loadJobs()
      setActiveTab("maintenance")
    } catch (e: any) {
      showAlert("Fehler", `Fehler beim Starten des Modell-Upgrades: ${e.message}`)
    }
  }

  async function triggerReboot() {
    showConfirm(
      "Reboot bestätigen",
      "Bist du sicher, dass du das gesamte Host-System neu starten willst?",
      async () => {
        try {
          await api("/api/maintenance/reboot", { method: "POST" })
          showAlert("Reboot", "Reboot ausgelöst. System startet neu...", () => {
            onClose()
          })
        } catch (e: any) {
          showAlert("Fehler", `Fehler beim Reboot: ${e.message}`)
        }
      }
    )
  }

  async function doBackup() {
    setBackupRunning(true)
    setBackupMsg("Snapshot wird erzeugt...")
    try {
      const r = await api<{ ok: boolean; snapshot: string; files: string[] }>("/api/system/backup", { method: "POST" })
      setBackupMsg(r.ok ? `Snapshot erzeugt: ${r.snapshot} (${r.files.length} Komponenten)` : "Backup fehlgeschlagen.")
      loadBackups()
    } catch (e: any) {
      setBackupMsg(`Fehler: ${e.message}`)
    } finally {
      setBackupRunning(false)
    }
  }

  async function restartService(serviceId: string) {
    setRestartingServices(prev => ({ ...prev, [serviceId]: true }))
    try {
      const res = await api<{ ok: boolean; err?: string }>("/api/maintenance/restart", {
        method: "POST",
        body: JSON.stringify({ service: serviceId })
      })
      if (res.ok) {
        showAlert("Dienst neu gestartet", `Dienst ${serviceId} wurde erfolgreich neu gestartet.`, () => {
          if (activeTab === "logs" && selectedService === serviceId) {
            loadServiceLogs(serviceId)
          }
        })
      } else {
        showAlert("Fehler", `Fehler beim Neustart: ${res.err || "Unbekannter Fehler"}`)
      }
    } catch (e: any) {
      showAlert("Fehler", `Fehler beim Neustart: ${e.message}`)
    } finally {
      setRestartingServices(prev => ({ ...prev, [serviceId]: false }))
    }
  }

  async function cancelJob(jobId: string) {
    try {
      await api(`/api/jobs/${jobId}/cancel`, { method: "POST" })
      loadJobs()
    } catch (e: any) {
      showAlert("Fehler", `Fehler beim Abbrechen: ${e.message}`)
    }
  }

  // Aktiver Wartungs-Job (System-Update) → UI-Aktionen sperren, Dashboard bleibt sichtbar.
  const maintenanceJob = jobs.find(j => (j.state === "running" || j.state === "queued") && j.group === "maintenance")

  return (
    <>
      {/* Backdrop */}
      <div 
        className={cn(
          "fixed inset-0 bg-black/60 backdrop-blur-sm z-50 transition-opacity duration-300",
          open ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"
        )}
        onClick={onClose}
      />

      {/* Drawer */}
      <div 
        className={cn(
          "fixed inset-y-0 right-0 w-full sm:w-[640px] bg-card/85 backdrop-blur-xl border-l border-border/60 shadow-2xl z-50 flex flex-col transform transition-transform duration-300 ease-in-out font-sans text-foreground",
          open ? "translate-x-0" : "translate-x-full"
        )}
      >
        {/* Header */}
        <div className="flex h-16 shrink-0 items-center justify-between border-b border-border/40 px-6">
          <div className="flex items-center gap-2">
            <Cpu className="h-4.5 w-4.5 text-primary" />
            <h2 className="text-sm font-semibold tracking-wide uppercase font-space">OS-Zentrale & Pflege</h2>
          </div>
          <button 
            onClick={onClose}
            className="flex h-8 w-8 items-center justify-center rounded-lg border border-border/40 text-muted-foreground hover:bg-accent transition-colors"
          >
            <X className="h-4 w-4" />
          </button>
        </div>

        {/* Navigation Tabs */}
        <div className="flex border-b border-border/40 px-6">
          <button 
            onClick={() => setActiveTab("maintenance")}
            className={cn(
              "flex-1 py-3 text-xs font-semibold uppercase tracking-wider border-b-2 text-center transition-all",
              activeTab === "maintenance" 
                ? "border-primary text-primary" 
                : "border-transparent text-muted-foreground hover:text-foreground"
            )}
          >
            System-Wartung
          </button>
          <button 
            onClick={() => setActiveTab("logs")}
            className={cn(
              "flex-1 py-3 text-xs font-semibold uppercase tracking-wider border-b-2 text-center transition-all",
              activeTab === "logs" 
                ? "border-primary text-primary" 
                : "border-transparent text-muted-foreground hover:text-foreground"
            )}
          >
            System-Logs
          </button>
          <button 
            onClick={() => setActiveTab("settings")}
            className={cn(
              "flex-1 py-3 text-xs font-semibold uppercase tracking-wider border-b-2 text-center transition-all",
              activeTab === "settings" 
                ? "border-primary text-primary" 
                : "border-transparent text-muted-foreground hover:text-foreground"
            )}
          >
            Einstellungen
          </button>
        </div>

        {/* Content */}
        <div className="flex-1 overflow-y-auto p-6 space-y-6">
          {activeTab === "maintenance" && (
            <>
              {/* Updates */}
              <div className="space-y-2.5">
                <div className="flex items-center justify-between">
                  <h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">Updates</h3>
                  <button onClick={triggerCheckUpdates} disabled={checkingUpdates || !!maintenanceJob}
                    className="flex items-center gap-1 text-[10px] font-semibold text-primary hover:text-primary/80 transition-colors disabled:opacity-50">
                    <RefreshCw className={cn("h-3 w-3", checkingUpdates && "animate-spin")} /> Nach Updates suchen
                  </button>
                </div>
                {updates?.last_check && (
                  <div className="text-[9px] text-muted-foreground -mt-1">Zuletzt gesucht: {formatLastCheck(updates.last_check)}</div>
                )}
                {maintenanceJob && (
                  <div className="flex items-center gap-2 rounded-lg border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-[11px] text-amber-300">
                    <RefreshCw className="h-3.5 w-3.5 shrink-0 animate-spin" />
                    <span>Update läuft: <span className="font-semibold">{maintenanceJob.label}</span> — bitte warten. Weitere Updates sind solange gesperrt.</span>
                  </div>
                )}
                <div className="space-y-1.5">
                  <UpdateRow icon={Shield} iconClass="text-cyan-400" name="OS-Pakete (apt)" available={!!updates?.os} status={updates?.os ? `${updates.os} verfügbar` : "aktuell"} actionLabel="Anzeigen" onAction={() => openUpdateDetails("os")} />
                  <UpdateRow icon={Server} iconClass="text-violet-400" name="Inferenz-Engine (llama.cpp)" available={!!updates?.engine} status={updates?.engine ? "Update verfügbar" : "aktuell"} actionLabel="Anzeigen" onAction={() => openUpdateDetails("engine")} />
                  <UpdateRow icon={Shuffle} iconClass="text-fuchsia-400" name="Router (llama-swap)" available={!!updates?.swap} status={updates?.swap ? "Update verfügbar" : "aktuell"} actionLabel="Anzeigen" onAction={() => openUpdateDetails("swap")} />
                  {(() => {
                    const h = updates?.components?.find((c) => c.key === "hermes_agent")
                    return (
                      <UpdateRow icon={Bot} iconClass="text-amber-400" name="Hermes-Agent" available={h?.update === true} busy={hermesUpdating} status={h?.update === true ? `Update: ${h.latest}` : h?.reachable === false ? "offline" : "aktuell"} actionLabel="Anzeigen" onAction={() => openUpdateDetails("hermes")} />
                    )
                  })()}
                  {updates?.model_list?.map((m) => (
                    <UpdateRow key={m.role} icon={Box} iconClass="text-emerald-400" name={`Modell · ${m.role}`} available={true} status={m.title} actionLabel="Upgrade" onAction={() => triggerModelUpgrade(m.repo, m.role)} />
                  ))}
                </div>
              </div>

              {/* Dienste */}
              <div className="space-y-2.5">
                <h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">Dienste</h3>
                <div className="space-y-1.5">
                  {SERVICES.map((s) => (
                    <ServiceRow key={s.id} label={s.label} system={s.type === "system"} ok={services?.services.find((x) => x.name.toLowerCase().includes(s.reach))?.ok} busy={restartingServices[s.id]} onRestart={() => restartService(s.id)} onLogs={() => { setSelectedService(s.id); setActiveTab("logs") }} />
                  ))}
                </div>
              </div>

              {/* Backup */}
              <div className="space-y-2.5">
                <h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">Backup</h3>
                <div className="rounded-lg border border-border/50 bg-background/20 px-3 py-2.5 flex items-center gap-3">
                  <div className="flex-1 min-w-0">
                    <div className="text-xs text-foreground truncate">{backups[0] ? `Letztes: ${backups[0].snapshot}` : "Noch kein Backup"}</div>
                    <div className="text-[10px] text-muted-foreground">{backups.length} Snapshots · Restore per CLI (restore.sh)</div>
                  </div>
                  <button onClick={doBackup} disabled={backupRunning} className="flex items-center gap-1.5 text-[11px] font-semibold rounded-lg px-2.5 py-1 bg-primary text-primary-foreground hover:opacity-90 transition-all cursor-pointer disabled:opacity-50 shrink-0">
                    <Camera className={cn("h-3.5 w-3.5", backupRunning && "animate-pulse")} /> Snapshot
                  </button>
                </div>
                {backupMsg && (
                  <div className="text-[10px] font-mono text-primary bg-primary/5 p-2 rounded-lg border border-primary/20 break-all leading-normal">{backupMsg}</div>
                )}
              </div>

              {/* Gefahrenzone */}
              <div className="space-y-2.5">
                <h3 className="text-xs font-bold uppercase tracking-wider text-red-400/80">Gefahrenzone</h3>
                <button onClick={triggerReboot} className="flex w-full items-center gap-3 p-3 rounded-lg border border-red-500/20 bg-red-500/5 hover:bg-red-500/10 text-red-400 transition-all text-left text-xs font-semibold">
                  <Power className="h-4.5 w-4.5" />
                  <div>
                    <div>Host-System neu starten</div>
                    <div className="text-[10px] text-red-400/80 font-normal">Startet die ganze Box neu</div>
                  </div>
                </button>
              </div>

              {/* Active Jobs */}
              <div className="space-y-3">
                <div className="flex items-center justify-between">
                  <h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">Hintergrund-Aufgaben</h3>
                  <span className="text-[10px] font-mono bg-primary/10 text-primary px-1.5 py-0.5 rounded-full">
                    {jobs.filter(j => j.state === "running" || j.state === "queued").length} Aktiv
                  </span>
                </div>

                <div className="space-y-3">
                  {jobs.length === 0 ? (
                    <div className="text-xs text-muted-foreground border border-dashed border-border/60 rounded-xl p-6 text-center">
                      Aktuell keine aktiven Hintergrund-Jobs.
                    </div>
                  ) : (
                    jobs.map((job) => {
                      const isActive = job.state === "running" || job.state === "queued"
                      return (
                        <div 
                          key={job.id} 
                          className={cn(
                            "p-3 rounded-xl border transition-all duration-300",
                            isActive 
                              ? "border-primary/40 bg-primary/5 shadow-md shadow-primary/5" 
                              : "border-border/40 bg-background/20 opacity-80"
                          )}
                        >
                          <div className="flex items-start justify-between gap-3">
                            <div className="space-y-1">
                              <div className="text-xs font-semibold flex items-center gap-1.5">
                                {isActive && (
                                  <span className="flex h-2 w-2 relative">
                                    <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75"></span>
                                    <span className="relative inline-flex rounded-full h-2 w-2 bg-primary"></span>
                                  </span>
                                )}
                                {job.label}
                              </div>
                              <div className="text-[10px] font-mono text-muted-foreground uppercase flex items-center gap-2">
                                <span>ID: {job.id}</span>
                                <span>•</span>
                                <span className={cn(
                                  job.state === "done" && "text-emerald-400",
                                  job.state === "failed" && "text-red-400",
                                  job.state === "running" && "text-primary",
                                  job.state === "queued" && "text-amber-400",
                                  job.state === "canceled" && "text-muted-foreground"
                                )}>
                                  {job.state}
                                </span>
                              </div>
                            </div>

                            {isActive && (
                              <button 
                                onClick={() => cancelJob(job.id)}
                                className="text-[10px] font-semibold text-red-400 hover:text-red-300 border border-red-500/20 bg-red-500/5 hover:bg-red-500/10 px-2 py-0.5 rounded transition-colors"
                              >
                                Abbrechen
                              </button>
                            )}
                          </div>

                          {/* Progress */}
                          {job.state === "running" && (
                            <div className="mt-3 space-y-1">
                              <div className="w-full h-1.5 bg-muted rounded-full overflow-hidden">
                                <div 
                                  className="h-full bg-primary transition-all duration-500" 
                                  style={{ width: `${job.progress ?? 0}%` }}
                                />
                              </div>
                              <div className="flex justify-between items-center text-[9px] font-mono text-muted-foreground">
                                <span>{job.progress ?? 0}%</span>
                                {job.done_bytes != null && job.total_bytes != null && (
                                  <span>
                                    {formatBytes(job.done_bytes)} / {formatBytes(job.total_bytes)}
                                    {job.rate_bps != null && ` (${formatBytes(job.rate_bps)}/s)`}
                                  </span>
                                )}
                                {job.eta_s != null && <span>ETA: {job.eta_s}s</span>}
                              </div>
                            </div>
                          )}
                        </div>
                      )
                    })
                  )}
                </div>
              </div>
            </>
          )}

          {activeTab === "logs" && (
            // Logs View
            <div className="flex flex-col h-full space-y-4">
              {/* Service Select & Restart */}
              <div className="flex items-center gap-2">
                <select 
                  value={selectedService} 
                  onChange={(e) => setSelectedService(e.target.value)}
                  className="flex-1 h-9 px-3 text-xs bg-background/40 border border-border/60 rounded-lg outline-none text-foreground font-semibold"
                >
                  {SERVICES.map((s) => (
                    <option key={s.id} value={s.id}>
                      {s.label} ({s.type === "system" ? "systemd-root" : "user"})
                    </option>
                  ))}
                </select>
                
                <button 
                  onClick={() => restartService(selectedService)}
                  disabled={restartingServices[selectedService]}
                  className="flex h-9 px-3 items-center gap-1.5 text-xs font-semibold rounded-lg border border-border/60 bg-background/20 hover:border-primary/50 transition-colors disabled:opacity-50"
                  title="Dienst neu starten"
                >
                  <RefreshCw className={cn("h-3.5 w-3.5", restartingServices[selectedService] && "animate-spin")} />
                  Restart
                </button>
              </div>

              {/* Log Console Container */}
              <div className="flex-1 flex flex-col min-h-[300px] border border-border/60 bg-black/50 rounded-xl overflow-hidden shadow-inner">
                {/* Console Header */}
                <div className="flex h-9 items-center justify-between px-4 border-b border-border/40 bg-black/30 shrink-0">
                  <div className="flex items-center gap-1.5 text-[10px] font-mono text-muted-foreground">
                    <Terminal className="h-3 w-3 text-primary" />
                    <span>stdout/stderr - {selectedService}</span>
                  </div>
                  <button 
                    onClick={() => loadServiceLogs(selectedService)}
                    disabled={loadingLogs}
                    className="text-muted-foreground hover:text-foreground transition-colors"
                  >
                    <RefreshCw className={cn("h-3 w-3", loadingLogs && "animate-spin")} />
                  </button>
                </div>

                {/* Console Log Area */}
                <pre 
                  ref={logContainerRef}
                  className="flex-1 p-4 overflow-y-auto text-[10px] font-mono text-cyan-300/90 whitespace-pre-wrap select-text leading-relaxed scrollbar-thin"
                >
                  {logStatus === "password_required" || logStatus === "incorrect_password" ? (
                    <div className="flex flex-col items-center justify-center p-6 text-center h-full space-y-3">
                      <AlertTriangle className="h-8 w-8 text-amber-400 animate-pulse animate-duration-1000" />
                      <div className="text-xs font-semibold text-amber-300">
                        {logStatus === "incorrect_password" ? "Falsches Sudo-Passwort hinterlegt." : "Sudo-Passwort für systemd-Dienste erforderlich."}
                      </div>
                      <p className="text-[10px] text-muted-foreground max-w-xs leading-normal">
                        Für das Auslesen der systemd-Logs von {selectedService} werden Root-Rechte benötigt. Hinterlege dein Passwort in den Einstellungen.
                      </p>
                      <button 
                        onClick={() => setActiveTab("settings")}
                        className="px-3 py-1.5 text-[10px] font-semibold text-primary-foreground bg-primary hover:bg-primary/95 rounded-md transition-colors mt-2"
                      >
                        Sudo-Passwort eintragen
                      </button>
                    </div>
                  ) : loadingLogs && !logs ? (
                    <span className="text-muted-foreground">Lade Logs...</span>
                  ) : (
                    logs || <span className="text-muted-foreground">Keine Logeinträge vorhanden.</span>
                  )}
                </pre>
              </div>
            </div>
          )}

          {activeTab === "settings" && (
            <div className="space-y-6">
              <div className="space-y-2">
                <h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">Zugangsdaten & Schlüssel</h3>
                <p className="text-[10px] text-muted-foreground leading-normal">
                  Diese Daten werden ausschließlich lokal in deinem Browser (localStorage) gespeichert und bei Bedarf an das Backend übertragen.
                </p>
              </div>

              {/* Sudo Passwort */}
              <div className="space-y-2">
                <label className="text-xs font-semibold flex items-center gap-1.5">
                  <Shield className="h-4 w-4 text-amber-400" />
                  Host Sudo-Passwort
                </label>
                <div className="relative">
                  <input
                    type={showSudo ? "text" : "password"}
                    value={sudoPasswordInput}
                    onChange={(e) => setSudoPasswordInput(e.target.value)}
                    aria-label="Host Sudo-Passwort"
                    name="sudo-password"
                    autoComplete="off"
                    spellCheck={false}
                    placeholder="Sudo-Passwort für System-Operationen"
                    className="w-full h-10 pl-3 pr-10 text-xs bg-background/40 border border-border/60 rounded-lg outline-none focus:border-primary transition-colors text-foreground"
                  />
                  <button
                    type="button"
                    onClick={() => setShowSudo(!showSudo)}
                    aria-label={showSudo ? "Passwort verbergen" : "Passwort anzeigen"}
                    className="absolute inset-y-0 right-0 flex items-center pr-3 text-muted-foreground hover:text-foreground transition-colors"
                  >
                    {showSudo ? <EyeOff className="h-4 w-4" aria-hidden="true" /> : <Eye className="h-4 w-4" aria-hidden="true" />}
                  </button>
                </div>
                <p className="text-[9px] text-muted-foreground leading-normal">
                  Wird benötigt für systemd-Dienste (Llama Swap logs/restart), OS-Update (apt) und Reboot.
                </p>
              </div>

              {/* HuggingFace Token */}
              <div className="space-y-2">
                <label className="text-xs font-semibold flex items-center gap-1.5">
                  <Key className="h-4 w-4 text-violet-400" />
                  HuggingFace API Token
                </label>
                <div className="relative">
                  <input
                    type={showHf ? "text" : "password"}
                    value={hfTokenInput}
                    onChange={(e) => setHfTokenInput(e.target.value)}
                    aria-label="HuggingFace API Token"
                    name="hf-token"
                    autoComplete="off"
                    spellCheck={false}
                    placeholder="hf_…"
                    className="w-full h-10 pl-3 pr-10 text-xs bg-background/40 border border-border/60 rounded-lg outline-none focus:border-primary transition-colors text-foreground"
                  />
                  <button
                    type="button"
                    onClick={() => setShowHf(!showHf)}
                    aria-label={showHf ? "Token verbergen" : "Token anzeigen"}
                    className="absolute inset-y-0 right-0 flex items-center pr-3 text-muted-foreground hover:text-foreground transition-colors"
                  >
                    {showHf ? <EyeOff className="h-4 w-4" aria-hidden="true" /> : <Eye className="h-4 w-4" aria-hidden="true" />}
                  </button>
                </div>
                <p className="text-[9px] text-muted-foreground leading-normal">
                  Erlaubt das Herunterladen von geschützten oder Gate-restricted Modellen direkt über Mission Control.
                </p>
              </div>

              {/* Buttons */}
              <div className="flex gap-3 pt-2">
                <button
                  onClick={() => {
                    localStorage.setItem("mc_sudo_password", sudoPasswordInput);
                    localStorage.setItem("mc_hf_token", hfTokenInput);
                    showAlert("Erfolgreich", "Einstellungen erfolgreich lokal gespeichert.");
                  }}
                  className="flex-1 h-9 flex items-center justify-center text-xs font-semibold text-primary-foreground bg-primary hover:bg-primary/90 rounded-lg transition-colors shadow shadow-primary/10 cursor-pointer"
                >
                  Speichern
                </button>
                <button
                  onClick={() => {
                    setSudoPasswordInput("");
                    setHfTokenInput("");
                    localStorage.removeItem("mc_sudo_password");
                    localStorage.removeItem("mc_hf_token");
                    showAlert("Gelöscht", "Zugangsdaten gelöscht.");
                  }}
                  className="h-9 px-4 flex items-center justify-center text-xs font-semibold text-muted-foreground border border-border/60 bg-background/20 hover:bg-accent rounded-lg transition-colors cursor-pointer"
                >
                  Zurücksetzen
                </button>
              </div>
            </div>
          )}
        </div>
      </div>

      {detail && (() => {
        const d = detail.data
        const meta = {
          os: { icon: Shield, cls: "text-cyan-400", title: "OS-Pakete (apt)" },
          engine: { icon: Server, cls: "text-violet-400", title: "Inferenz-Engine (llama.cpp)" },
          swap: { icon: Shuffle, cls: "text-fuchsia-400", title: "Router (llama-swap)" },
          hermes: { icon: Bot, cls: "text-amber-400", title: "Hermes-Agent" },
        }[detail.kind]
        const Icon = meta.icon
        const nothing = !d ? true
          : detail.kind === "os" ? (d.count ?? 0) === 0
          : detail.kind === "hermes" ? (d.behind ?? 0) === 0
          : (d.installed_build != null && d.latest_build != null && d.latest_build <= d.installed_build)
        return (
          <div className="fixed inset-0 z-[60] flex items-center justify-center p-4">
            <div className="absolute inset-0 bg-black/70 backdrop-blur-sm" onClick={() => setDetail(null)} />
            <div className="relative w-full max-w-lg max-h-[80vh] flex flex-col rounded-2xl border border-border/60 bg-card shadow-2xl font-sans text-foreground">
              {/* Header */}
              <div className="flex h-14 shrink-0 items-center justify-between border-b border-border/40 px-5">
                <div className="flex items-center gap-2">
                  <Icon className={cn("h-4.5 w-4.5", meta.cls)} />
                  <h3 className="text-sm font-semibold">{meta.title}</h3>
                </div>
                <button onClick={() => setDetail(null)} className="flex h-7 w-7 items-center justify-center rounded-lg border border-border/40 text-muted-foreground hover:bg-accent transition-colors">
                  <X className="h-4 w-4" />
                </button>
              </div>

              {/* Body */}
              <div className="flex-1 overflow-y-auto p-5 text-xs space-y-3 scrollbar-thin">
                {detail.loading ? (
                  <div className="flex h-24 items-center justify-center gap-2 text-muted-foreground">
                    <RefreshCw className="h-4 w-4 animate-spin" /> Details werden geladen…
                  </div>
                ) : d?.error ? (
                  <div className="rounded-lg border border-red-500/30 bg-red-500/5 p-3 text-red-400">{d.error}</div>
                ) : detail.kind === "os" ? (
                  (d?.count ?? 0) === 0 ? (
                    <div className="text-muted-foreground">Keine Pakete zu aktualisieren — System ist aktuell.</div>
                  ) : (
                    <>
                      <div className="text-muted-foreground">{d!.count} Paket(e) werden aktualisiert:</div>
                      <div className="space-y-1">
                        {d!.packages!.map((p) => (
                          <div key={p.name} className="flex items-center justify-between gap-2 rounded-md border border-border/40 bg-background/30 px-2.5 py-1.5">
                            <span className="flex items-center gap-1.5 font-mono text-[11px] truncate">
                              <Package className="h-3 w-3 text-cyan-400 shrink-0" />{p.name}
                            </span>
                            <span className="flex items-center gap-1 font-mono text-[10px] text-muted-foreground shrink-0">
                              <span>{p.current}</span><ArrowRight className="h-3 w-3" /><span className="text-emerald-400">{p.candidate}</span>
                            </span>
                          </div>
                        ))}
                      </div>
                    </>
                  )
                ) : detail.kind === "engine" || detail.kind === "swap" ? (
                  <>
                    <div className="flex items-center gap-2 font-mono text-[11px]">
                      <span className="rounded-md border border-border/40 bg-background/30 px-2 py-1">Build {d?.installed_build ?? "?"}</span>
                      <ArrowRight className="h-3.5 w-3.5 text-muted-foreground" />
                      <span className="rounded-md border border-emerald-500/30 bg-emerald-500/5 px-2 py-1 text-emerald-400">Build {d?.latest_build ?? "?"}</span>
                    </div>
                    {(d?.name || d?.latest_tag) && (
                      <div className="text-muted-foreground">Release: <span className="text-foreground">{d?.name}</span>{d?.latest_tag ? ` (${d.latest_tag})` : ""}</div>
                    )}
                    {d?.url && (
                      <a href={d.url} target="_blank" rel="noreferrer" className="inline-flex items-center gap-1 text-primary hover:underline">
                        Release-Notes auf GitHub <ExternalLink className="h-3 w-3" />
                      </a>
                    )}
                    {d?.body && (
                      <pre className="whitespace-pre-wrap rounded-lg border border-border/40 bg-background/30 p-3 text-[10px] leading-relaxed text-muted-foreground max-h-60 overflow-y-auto scrollbar-thin">{d.body}</pre>
                    )}
                  </>
                ) : (
                  // hermes
                  (d?.commits?.length ?? 0) === 0 ? (
                    <div className="text-muted-foreground">Keine neuen Commits — Hermes-Agent ist bereits aktuell.</div>
                  ) : (
                    <>
                      <div className="text-muted-foreground">{d!.behind} neue Commit(s) auf <span className="font-mono text-foreground">origin/{d!.branch}</span>:</div>
                      <div className="space-y-1">
                        {d!.commits!.map((c) => (
                          <div key={c.hash} className="flex items-start gap-2 rounded-md border border-border/40 bg-background/30 px-2.5 py-1.5">
                            <GitCommit className="h-3.5 w-3.5 text-primary shrink-0 mt-0.5" />
                            <div className="min-w-0">
                              <div className="text-[11px] truncate">{c.subject}</div>
                              <div className="font-mono text-[9px] text-muted-foreground">{c.hash} · {c.when}</div>
                            </div>
                          </div>
                        ))}
                      </div>
                      <p className="text-[10px] text-muted-foreground leading-normal">Vor dem Update wird automatisch ein Backup erstellt; danach startet der Hermes-Gateway neu.</p>
                    </>
                  )
                )}
              </div>

              {/* Footer */}
              <div className="flex gap-3 border-t border-border/40 p-4 shrink-0">
                <button onClick={() => setDetail(null)} className="h-9 flex-1 rounded-lg border border-border/60 bg-background/20 text-xs font-semibold text-muted-foreground hover:bg-accent transition-colors cursor-pointer">
                  Schließen
                </button>
                <button onClick={applyFromDetail} disabled={detail.loading || nothing || !!maintenanceJob}
                  title={maintenanceJob ? `Update läuft bereits: ${maintenanceJob.label}` : undefined}
                  className="h-9 flex-1 rounded-lg bg-primary text-xs font-semibold text-primary-foreground hover:opacity-90 transition-all cursor-pointer disabled:opacity-40 disabled:cursor-default">
                  {maintenanceJob ? "Update läuft…" : "Jetzt aktualisieren"}
                </button>
              </div>
            </div>
          </div>
        )
      })()}

      {dialog && (
        <CustomDialog
          type={dialog.type}
          title={dialog.title}
          message={dialog.message}
          onConfirm={dialog.onConfirm}
          onCancel={dialog.onCancel}
        />
      )}
    </>
  )
}
