// „Geht's Lucy gut?" — bündelt die vielen technischen Status-Signale zu wenigen
// Lucy-Fähigkeiten in Klartext, inkl. Gesamt-Verdikt, Speicher-Ampel und einer
// konkreten 1-Klick-Reparatur pro Problem. EINE Quelle für das Status-Panel.

import { Brain, BookMarked, Eye, Plug, Bot, Mic, type LucideIcon } from "lucide-react"
import { useHealth, useServices, useModels, useSystemStatus } from "./queries"

export type CheckStatus = "ok" | "warn" | "down" | "loading"

// Reparatur-Rezept: entweder einen systemd-Dienst neu starten oder ein Modell laden.
// WICHTIG: `service` sind die ECHTEN Unit-Namen (nicht die Anzeige-Namen der
// Dienste-Karte), damit /api/maintenance/restart sie akzeptiert.
export type Repair =
  | { kind: "restart"; service: string; label: string; needsSudo?: boolean }
  | { kind: "loadModel"; model: string; label: string }

export interface LucyCheck {
  id: string
  label: string        // Klartext-Name der Fähigkeit
  icon: LucideIcon
  status: CheckStatus
  detail: string       // Ein Satz: was ist gerade los
  critical: boolean    // zählt fürs Gesamt-Verdikt „Problem"
  repair?: Repair
}

export type Verdict = "loading" | "gut" | "warn" | "problem"

export interface MemoryAmpel {
  status: "ok" | "warn" | "full" | "unknown"
  usedGb: number
  totalGb: number
  pct: number
  text: string
}

export interface LucyHealth {
  verdict: Verdict
  checks: LucyCheck[]
  memory: MemoryAmpel
  problems: LucyCheck[]   // kritische Down-Checks (für den Schnellzugriff im Banner)
  warns: LucyCheck[]      // nicht-kritische Hinweise — damit das Banner SAGT, was los ist
}

export function useLucyHealth(): LucyHealth {
  const { data: health } = useHealth()
  const { data: svc } = useServices()
  const { data: modelsResp } = useModels()
  const { data: sys } = useSystemStatus()

  const loaded = !!health && !!svc
  const svcOk = (frag: string): boolean | undefined =>
    svc?.services.find((s) => s.name.toLowerCase().includes(frag))?.ok

  const engineOk = health?.engine_reachable
  const brainReady = health?.brain?.ready
  const brainName =
    health?.brain?.model ||
    modelsResp?.models.find((m) => m.role === "hermes")?.name ||
    ""

  const checks: LucyCheck[] = []

  // 1) Lucys Hirn — die wichtigste Fähigkeit. Engine läuft UND das Hirn-Modell ist geladen?
  checks.push(((): LucyCheck => {
    const base = { id: "brain", label: "Lucys Hirn", icon: Brain, critical: true }
    if (!loaded) return { ...base, status: "loading", detail: "Wird geprüft …" }
    if (engineOk === false)
      return {
        ...base,
        status: "down",
        detail: "Die Motor-Maschine (Engine) läuft nicht — Lucy kann gerade gar nicht denken.",
        repair: { kind: "restart", service: "llama-swap", label: "Motor neu starten", needsSudo: true },
      }
    if (brainReady === false)
      return {
        ...base,
        status: "down",
        detail: "Lucys Hirn ist gerade eingeschlafen — einmal aufwecken.",
        repair: brainName
          ? { kind: "loadModel", model: brainName, label: "Hirn aufwecken" }
          : undefined,
      }
    return { ...base, status: "ok", detail: "Wach und ansprechbar." }
  })())

  // 2) Lucys Augen — das Vision-Modell (Rolle `vision`). Seit der Warm-Set-Diät 07.07. ist
  // ON-DEMAND der NORMALZUSTAND (User-Entscheid: Augen nur, wenn Lucy an ist / IDE sie ruft;
  // die Lucy-App wärmt sie beim Start selbst an). Ruhende Augen sind darum OK, keine Warnung.
  checks.push(((): LucyCheck => {
    const base = { id: "vision", label: "Lucys Augen", icon: Eye, critical: false }
    if (!loaded || !modelsResp) return { ...base, status: "loading", detail: "Wird geprüft …" }
    const vm = modelsResp.models.find((m) => m.role === "vision")
    if (!vm)
      return { ...base, status: "warn", detail: "Kein Augen-Modell eingerichtet — Lucy kann keine Bilder ansehen." }
    const warm = (modelsResp.running ?? []).includes(vm.name)
    return warm
      ? { ...base, status: "ok", detail: "Sieht gerade zu (geladen, solange Lucy sie nutzt)." }
      : {
          ...base,
          status: "ok",
          detail: "Augen ruhen — sie laden von selbst, sobald Lucy startet oder ein Bild kommt.",
          repair: { kind: "loadModel", model: vm.name, label: "Augen wecken" },
        }
  })())

  // 3) Lucys Gedächtnis — Mem0-Dienst.
  checks.push(((): LucyCheck => {
    const base = { id: "memory", label: "Lucys Gedächtnis", icon: BookMarked, critical: true }
    const ok = svcOk("mem0")
    if (!loaded || ok === undefined) return { ...base, status: "loading", detail: "Wird geprüft …" }
    return ok
      ? { ...base, status: "ok", detail: "Merkt sich Neues und findet Altes wieder." }
      : {
          ...base,
          status: "down",
          detail: "Lucy kann sich gerade nichts merken — das Gedächtnis antwortet nicht.",
          repair: { kind: "restart", service: "mem0-service", label: "Gedächtnis neu starten" },
        }
  })())

  // 4) Verbindung (Gateway) — der integrierte OpenAI-Gateway, über den Apps/IDEs Lucy erreichen.
  checks.push(((): LucyCheck => {
    const base = { id: "gateway", label: "Verbindung (Gateway)", icon: Plug, critical: true }
    const ok = health ? health.gateway_reachable : svcOk("integriert")
    if (!loaded || ok === undefined) return { ...base, status: "loading", detail: "Wird geprüft …" }
    return ok
      ? { ...base, status: "ok", detail: "Apps und IDEs können Lucy erreichen." }
      : {
          ...base,
          status: "down",
          detail: "Die Verbindungs-Zentrale antwortet nicht — Apps erreichen Lucy nicht.",
          repair: { kind: "restart", service: "mission-control-2", label: "Zentrale neu starten" },
        }
  })())

  // 5) Lucys Agent (Hermes) — der Dienst, der als Lucy antwortet (Terminal/Telegram/Sprechen).
  checks.push(((): LucyCheck => {
    const base = { id: "agent", label: "Lucys Agent (Hermes)", icon: Bot, critical: true }
    const ok = svcOk("hermes-gateway")
    if (!loaded || ok === undefined) return { ...base, status: "loading", detail: "Wird geprüft …" }
    return ok
      ? { ...base, status: "ok", detail: "Lucy ist bereit zu reden und zu handeln." }
      : {
          ...base,
          status: "down",
          detail: "Lucys Agent ist offline — sie reagiert gerade nicht.",
          repair: { kind: "restart", service: "hermes-gateway", label: "Agent neu starten" },
        }
  })())

  // 6) Lucys Stimme — Voice-Dienst (STT/TTS). Nicht kritisch: Chat geht auch ohne.
  checks.push(((): LucyCheck => {
    const base = { id: "voice", label: "Lucys Stimme", icon: Mic, critical: false }
    const ok = svcOk("voice")
    if (!loaded || ok === undefined) return { ...base, status: "loading", detail: "Wird geprüft …" }
    return ok
      ? { ...base, status: "ok", detail: "Lucy kann hören und sprechen." }
      : {
          ...base,
          status: "warn",
          detail: "Sprechen ist gerade aus — Tippen geht weiter normal.",
          repair: { kind: "restart", service: "voice-service", label: "Stimme neu starten" },
        }
  })())

  // Speicher-Ampel = System-RAM, DIESELBE Quelle wie die RAM-Zeile in der
  // System-Status-Kachel. Vorher zeigte die Pille den GTT-Pool (GPU-Sicht auf den
  // Unified-Memory) — der weicht auf der APU vom System-RAM ab, wodurch „Box gesund"
  // und „System-Status" zwei verschiedene Speicher-Zahlen zeigten. Eine Box, eine Zahl.
  // Schwellen am RAM-Charakter geeicht: 4 Modelle warm ≈ 78 % gilt als gesund → grün.
  const total = sys?.ram?.total ?? 0
  const used = sys?.ram?.used ?? 0
  const pct = sys?.ram?.percent ?? (total > 0 ? Math.min(100, (used / total) * 100) : 0)
  const B = 1024 ** 3
  const memory: MemoryAmpel = !total
    ? { status: "unknown", usedGb: 0, totalGb: 0, pct: 0, text: "Speicher-Auslastung unbekannt." }
    : pct >= 93
      ? { status: "full", usedGb: used / B, totalGb: total / B, pct, text: "Speicher fast voll — Lucy könnte langsamer werden." }
      : pct >= 85
        ? { status: "warn", usedGb: used / B, totalGb: total / B, pct, text: "Speicher gut gefüllt — noch okay." }
        : { status: "ok", usedGb: used / B, totalGb: total / B, pct, text: "Genug Speicher frei." }

  const anyLoading = checks.some((c) => c.status === "loading")
  const problems = checks.filter((c) => c.critical && c.status === "down")
  const warns = checks.filter((c) => c.status === "warn" || (!c.critical && c.status === "down"))
  const memBad = memory.status === "full"

  const verdict: Verdict = anyLoading && !problems.length
    ? "loading"
    : problems.length
      ? "problem"
      : warns.length || memBad
        ? "warn"
        : "gut"

  return { verdict, checks, memory, problems, warns }
}
