import { useMemo, useState } from "react"
import {
  Sparkles, Wrench, Package, Loader2, CheckCircle2, XCircle, CircleDot,
  ChevronDown, ChevronRight, BookOpen, type LucideIcon,
} from "lucide-react"
import { api, type EigenlebenEintrag, type EigenlebenSkill } from "@/lib/api"
import { useEigenleben } from "@/lib/queries"
import { cn } from "@/lib/utils"

// „Von allein" — die Antwort auf die User-Frage vom 15.07.2026: EIN Ort, der zeigt,
// was die Box selbst geleistet hat. Oben die Skills (Lucys Fähigkeiten-Regal, selbst
// erstellte zuerst, mit Klartext-Beschreibung + Nutzungszähler), darunter die
// Vorschlags-Bilanz (angenommen/abgelehnt mit Grund) — ohne Chronik-Rauschen.

const HERKUNFT_UI: Record<EigenlebenSkill["herkunft"], { icon: LucideIcon; cls: string; erklaerung: string }> = {
  selbst: {
    icon: Sparkles,
    cls: "text-emerald-300 bg-emerald-500/10 border-emerald-500/30",
    erklaerung: "Diese Skills hat sich die Box selbst geschrieben — niemand hat sie ihr installiert.",
  },
  repo: {
    icon: Wrench,
    cls: "text-primary bg-primary/10 border-primary/25",
    erklaerung: "Von uns gebaut und über das Repo installiert (deploy/skills).",
  },
  bundled: {
    icon: Package,
    cls: "text-muted-foreground bg-background/40 border-border/50",
    erklaerung: "Kamen mit Hermes mit — Standard-Ausstattung.",
  },
}

// Hermes-Skill-States in Klartext (Quelle: banner/use_count-Daten; unbekannte Werte roh anzeigen).
const STATUS_LABEL: Record<string, string> = {
  disabled: "abgeschaltet",
  deprecated: "veraltet",
  broken: "defekt",
  error: "Fehler",
}

function datumKurz(iso: string | null): string {
  if (!iso) return "—"
  const d = new Date(iso)
  return isNaN(d.getTime()) ? "—" : d.toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "2-digit" })
}

export function EigenlebenView() {
  const { data, isLoading } = useEigenleben()

  const gruppen = useMemo(() => {
    const g: { herkunft: EigenlebenSkill["herkunft"]; label: string; skills: EigenlebenSkill[] }[] = []
    for (const s of data?.skills ?? []) {
      const last = g[g.length - 1]
      if (last && last.herkunft === s.herkunft) last.skills.push(s)
      else g.push({ herkunft: s.herkunft, label: s.herkunft_label, skills: [s] })
    }
    return g
  }, [data])

  return (
    <div className="space-y-7">
      <div>
        <h1 className="bg-gradient-to-r from-foreground via-foreground to-primary bg-clip-text font-space text-2xl font-bold tracking-tight text-transparent">
          Skills
        </h1>
        <p className="text-sm text-muted-foreground">
          Die Fähigkeiten deiner Box — mit Herkunft, Nutzung und ob der Agent sie gerade laden kann
          (aktiv/inaktiv). Das ist derselbe Skill-Satz, mit dem Lucy spricht und die Nacht-Worker
          arbeiten. Darunter: was aus den Vorschlägen der Box wurde.
        </p>
      </div>

      {isLoading && (
        <div className="flex items-center gap-2 rounded-2xl border border-border/60 bg-card/30 p-6 text-xs text-muted-foreground">
          <Loader2 className="h-4 w-4 animate-spin" /> Wird geladen …
        </div>
      )}

      {data && !data.available && (
        <div className="rounded-2xl border border-amber-500/30 bg-amber-500/5 p-4 text-xs text-amber-300">
          Die Skills liegen auf der Box (~/.hermes/skills) — im lokalen Dev-Modus nicht verfügbar.
        </div>
      )}

      {data?.available && (
        <>
          {/* Bilanz-Zähler */}
          <div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
            <Zahl label="Skills gesamt" wert={data.skills.length} />
            <Zahl label="davon selbst erstellt" wert={data.selbst_erstellt} betone />
            <Zahl label="Vorschläge angenommen" wert={data.bilanz.angenommen} />
            <Zahl label="Vorschläge abgelehnt" wert={data.bilanz.abgelehnt} />
          </div>

          {/* Skills nach Herkunft */}
          {gruppen.map((g) => {
            const ui = HERKUNFT_UI[g.herkunft]
            const Icon = ui.icon
            return (
              <section key={g.herkunft} className="space-y-3">
                <div>
                  <p className={cn("inline-flex items-center gap-1.5 rounded-md border px-2 py-1 text-[11px] font-bold", ui.cls)}>
                    <Icon className="h-3.5 w-3.5" /> {g.label} · {g.skills.length}
                  </p>
                  <p className="mt-1 text-[11px] text-muted-foreground/70">{ui.erklaerung}</p>
                </div>
                <div className="grid gap-2 md:grid-cols-2">
                  {g.skills.map((s) => <SkillKarte key={s.id} skill={s} />)}
                </div>
              </section>
            )
          })}

          {/* Vorschlags-Bilanz */}
          <Bilanz eintraege={data.bilanz.eintraege} />
        </>
      )}
    </div>
  )
}

function Zahl({ label, wert, betone }: { label: string; wert: number; betone?: boolean }) {
  return (
    <div className={cn("rounded-xl border p-3", betone ? "border-emerald-500/30 bg-emerald-500/5" : "border-border/50 bg-card/40")}>
      <p className={cn("font-space text-xl font-bold", betone ? "text-emerald-300" : "text-foreground")}>{wert}</p>
      <p className="text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/70">{label}</p>
    </div>
  )
}

function SkillKarte({ skill }: { skill: EigenlebenSkill }) {
  const [offen, setOffen] = useState(false)
  const [text, setText] = useState<string | null>(null)
  const [laedt, setLaedt] = useState(false)

  async function toggle() {
    const next = !offen
    setOffen(next)
    if (next && text === null && !laedt) {
      setLaedt(true)
      try {
        const r = await api<{ id: string; text: string }>(`/api/eigenleben/skill/${encodeURIComponent(skill.id)}`)
        setText(r.text)
      } catch {
        setText("(Konnte den Skill-Text nicht laden.)")
      } finally {
        setLaedt(false)
      }
    }
  }

  return (
    <div className="rounded-xl border border-border/50 bg-card/40 p-3 backdrop-blur-sm">
      <button onClick={toggle} className="flex w-full items-start gap-2 text-left cursor-pointer">
        {offen ? <ChevronDown className="mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" /> : <ChevronRight className="mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" />}
        <div className="min-w-0 flex-1">
          <div className="flex flex-wrap items-center gap-2">
            <span className="text-sm font-semibold text-foreground">{skill.name}</span>
            {skill.aktiv === true && (
              <span className="flex items-center gap-1 rounded bg-emerald-500/10 px-1.5 py-0.5 text-[9px] font-bold text-emerald-300"
                title="Der Agent kann diesen Skill laden und nutzen.">
                <span className="h-1.5 w-1.5 rounded-full bg-emerald-400" /> aktiv
              </span>
            )}
            {skill.aktiv === false && (
              <span className="flex items-center gap-1 rounded bg-zinc-500/10 px-1.5 py-0.5 text-[9px] font-bold text-zinc-400"
                title="Der Agent kann diesen Skill gerade NICHT laden — Plattform passt nicht (z. B. Apple-Skills auf Linux), Voraussetzungen fehlen oder per Config abgeschaltet.">
                <span className="h-1.5 w-1.5 rounded-full bg-zinc-500" /> inaktiv
              </span>
            )}
            {skill.kategorie && (
              <span className="rounded bg-background/60 px-1.5 py-0.5 text-[9px] font-semibold text-muted-foreground/80">{skill.kategorie}</span>
            )}
            {skill.genutzt > 0 && (
              <span className="rounded bg-primary/10 px-1.5 py-0.5 text-[9px] font-bold text-primary" title={`zuletzt: ${datumKurz(skill.zuletzt_genutzt)}`}>
                {skill.genutzt}× genutzt
              </span>
            )}
            {skill.status !== "active" && (
              <span className="rounded bg-amber-500/10 px-1.5 py-0.5 text-[9px] font-bold text-amber-300">
                {STATUS_LABEL[skill.status] ?? skill.status}
              </span>
            )}
          </div>
          <p className={cn("mt-1 text-xs leading-relaxed text-foreground/75", !offen && "line-clamp-2")}>
            {skill.beschreibung || "(keine Beschreibung im Skill hinterlegt)"}
          </p>
        </div>
      </button>
      {offen && (
        <div className="mt-2 border-t border-border/40 pt-2">
          <p className="mb-1.5 flex items-center gap-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/60">
            <BookOpen className="h-3 w-3" /> So funktioniert er (SKILL.md){skill.autor ? ` · Autor: ${skill.autor}` : ""}
          </p>
          {laedt
            ? <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
            : <pre className="max-h-80 overflow-y-auto whitespace-pre-wrap rounded-lg bg-background/50 p-2.5 font-mono text-[10.5px] leading-relaxed text-foreground/80 scrollbar-thin">{text ?? ""}</pre>}
        </div>
      )}
    </div>
  )
}

function Bilanz({ eintraege }: { eintraege: EigenlebenEintrag[] }) {
  const [alle, setAlle] = useState(false)
  const shown = alle ? eintraege : eintraege.slice(0, 12)
  return (
    <section className="space-y-3">
      <p className="flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/60">
        <CircleDot className="h-3.5 w-3.5" /> Vorschlags-Bilanz — was die Box vorschlug und was daraus wurde
      </p>
      {eintraege.length === 0 && (
        <div className="rounded-2xl border border-dashed border-border/60 bg-card/20 p-6 text-center text-xs text-muted-foreground">
          Noch keine Vorschläge verbucht. Sobald die Box etwas vorschlägt und du klickst, steht die Entscheidung hier.
        </div>
      )}
      <div className="space-y-2">
        {shown.map((e, i) => {
          const angenommen = e.art === "angenommen"
          const Icon = angenommen ? CheckCircle2 : e.art === "abgelehnt" ? XCircle : CircleDot
          return (
            <div key={`${e.titel}-${e.ts}-${i}`} className="flex items-start gap-2.5 rounded-xl border border-border/50 bg-card/40 p-3">
              <Icon className={cn("mt-0.5 h-4 w-4 shrink-0",
                angenommen ? "text-emerald-400" : e.art === "abgelehnt" ? "text-red-400" : "text-amber-300")} />
              <div className="min-w-0 flex-1">
                <div className="flex flex-wrap items-center gap-2">
                  <span className="font-mono text-xs font-semibold text-foreground">{e.titel}</span>
                  <span className={cn("rounded px-1.5 py-0.5 text-[9px] font-bold uppercase",
                    angenommen ? "bg-emerald-500/10 text-emerald-300" : e.art === "abgelehnt" ? "bg-red-500/10 text-red-300" : "bg-amber-500/10 text-amber-300")}>
                    {e.art}
                  </span>
                  <span className="ml-auto font-mono text-[10px] text-muted-foreground/60">
                    {e.ts ? new Date(e.ts * 1000).toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit" }) : ""}
                  </span>
                </div>
                {e.detail && <p className="mt-1 text-xs leading-relaxed text-foreground/70">{e.detail}</p>}
              </div>
            </div>
          )
        })}
      </div>
      {!alle && eintraege.length > 12 && (
        <button onClick={() => setAlle(true)} className="text-[11px] text-muted-foreground underline hover:text-foreground cursor-pointer">
          Alle {eintraege.length} Einträge anzeigen
        </button>
      )}
    </section>
  )
}
