import { useMemo, useState } from "react"
import {
  History, HeartPulse, ShieldAlert, Bell, Moon, Radar, Inbox, Loader2,
  Archive, RotateCcw, AlarmClock, MessageCircle, Sparkles, type LucideIcon,
} from "lucide-react"
import { api, type ChronikItem, type Snapshot } from "@/lib/api"
import { useChronik, useZeitmaschine, useQueryClient, qk } from "@/lib/queries"
import { useDialog } from "@/lib/useDialog"
import { cn } from "@/lib/utils"

// Chronik = die lesbare Geschichte dessen, was die Box von allein getan und gemeldet hat
// (Quelle: Melde-Briefkasten). Daneben die Zeitmaschine: Snapshots ansehen und per Klick
// zu einem Stand zurückkehren — mit hartem Bestätigungsdialog und Pre-Restore-Sicherung.

const SOURCE_UI: Record<string, { icon: LucideIcon; label: string; cls: string }> = {
  sentry: { icon: HeartPulse, label: "Health-Wächter", cls: "text-red-300 bg-red-500/10 border-red-500/25" },
  alarm: { icon: ShieldAlert, label: "Alarm", cls: "text-red-200 bg-red-500/15 border-red-500/40" },
  notify: { icon: Bell, label: "Meldung", cls: "text-sky-300 bg-sky-500/10 border-sky-500/25" },
  "chef-gutachter": { icon: Moon, label: "Morgenlage", cls: "text-violet-300 bg-violet-500/10 border-violet-500/25" },
  radar: { icon: Radar, label: "Radar", cls: "text-teal-300 bg-teal-500/10 border-teal-500/25" },
  auftragsbuch: { icon: Inbox, label: "Auftragsbuch", cls: "text-primary bg-primary/10 border-primary/25" },
  zeitmaschine: { icon: RotateCcw, label: "Zeitmaschine", cls: "text-amber-300 bg-amber-500/10 border-amber-500/25" },
  reminder: { icon: AlarmClock, label: "Erinnerung", cls: "text-amber-300 bg-amber-500/10 border-amber-500/25" },
  traum: { icon: Sparkles, label: "Traum", cls: "text-violet-300 bg-violet-500/10 border-violet-500/25" },
}
const SOURCE_FALLBACK = { icon: MessageCircle, label: "Box", cls: "text-muted-foreground bg-background/40 border-border/50" }

function dayKey(ts: number): string {
  return new Date(ts * 1000).toLocaleDateString("de-DE", { weekday: "long", day: "2-digit", month: "long" })
}

export function ChronikView() {
  const { data: items = [], isLoading } = useChronik()
  const [limitPerDay, setLimitPerDay] = useState(true)

  const grouped = useMemo(() => {
    const g: { day: string; items: ChronikItem[] }[] = []
    for (const it of items) {
      const day = dayKey(it.ts)
      const last = g[g.length - 1]
      if (last && last.day === day) last.items.push(it)
      else g.push({ day, items: [it] })
    }
    return g
  }, [items])

  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">
          Chronik
        </h1>
        <p className="text-sm text-muted-foreground">
          Was deine Box von allein getan und gemeldet hat — und die Zeitmaschine, falls du zu einem früheren Stand zurück willst.
        </p>
      </div>

      <Zeitmaschine />

      <section className="space-y-4">
        <p className="flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/60">
          <History className="h-3.5 w-3.5" /> Verlauf
        </p>

        {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" /> Chronik wird geladen …
          </div>
        )}

        {!isLoading && items.length === 0 && (
          <div className="rounded-2xl border border-dashed border-border/60 bg-card/20 p-8 text-center text-xs text-muted-foreground">
            Noch keine Einträge. Sobald die Box etwas von allein tut oder meldet (Updates, Wächter, Träume), steht es hier.
          </div>
        )}

        {grouped.map(({ day, items: dayItems }) => (
          <div key={day}>
            <p className="mb-2 text-xs font-bold text-foreground/70">{day}</p>
            <div className="space-y-2 border-l-2 border-border/40 pl-4">
              {(limitPerDay ? dayItems.slice(0, 8) : dayItems).map((it) => {
                const ui = SOURCE_UI[it.source] ?? SOURCE_FALLBACK
                const Icon = ui.icon
                return (
                  <div key={it.id} className="relative rounded-xl border border-border/50 bg-card/40 p-3 backdrop-blur-sm">
                    <span className="absolute -left-[23px] top-4 h-2.5 w-2.5 rounded-full bg-border ring-4 ring-background/60" />
                    <div className="flex flex-wrap items-center gap-2">
                      <span className={cn("flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-[10px] font-bold", ui.cls)}>
                        <Icon className="h-3 w-3" /> {ui.label}
                      </span>
                      {it.subject && <span className="text-[10px] font-semibold text-muted-foreground">{it.subject}</span>}
                      <span className="ml-auto font-mono text-[10px] text-muted-foreground/60">
                        {new Date(it.ts * 1000).toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" })}
                      </span>
                    </div>
                    <p className="mt-1.5 whitespace-pre-wrap text-xs leading-relaxed text-foreground/85">{it.text}</p>
                  </div>
                )
              })}
              {limitPerDay && dayItems.length > 8 && (
                <button onClick={() => setLimitPerDay(false)} className="text-[11px] text-muted-foreground underline hover:text-foreground">
                  {dayItems.length - 8} weitere anzeigen
                </button>
              )}
            </div>
          </div>
        ))}
      </section>
    </div>
  )
}

// ── Zeitmaschine: Snapshots + Ein-Klick-Restore ───────────────────────────────
function Zeitmaschine() {
  const { data } = useZeitmaschine()
  const qc = useQueryClient()
  const { showAlert, showConfirm, dialogElement } = useDialog()
  const [busy, setBusy] = useState<string | null>(null)
  const [backupBusy, setBackupBusy] = useState(false)
  const [showAll, setShowAll] = useState(false)

  const backups = data?.backups ?? []
  const shown = showAll ? backups : backups.slice(0, 4)

  function fmtSnap(s: Snapshot): string {
    // Zeitstempel aus backup.sh ist kompakt (20260708-181136) — lesbar machen;
    // tolerant auch für Varianten mit Trennzeichen (2026-07-08T18-11).
    const m = s.snapshot.match(/^(\d{4})-?(\d{2})-?(\d{2})[T_-](\d{2})[-:]?(\d{2})/)
    if (!m) return s.snapshot
    return `${m[3]}.${m[2]}.${m[1]}, ${m[4]}:${m[5]} Uhr`
  }

  async function restore(s: Snapshot) {
    setBusy(s.file)
    try {
      await api("/api/zeitmaschine/restore", { method: "POST", body: JSON.stringify({ file: s.file }) })
      showAlert("Zeitmaschine läuft",
        "Die Wiederherstellung wurde gestartet. Die Dienste starten gleich neu — die Zentrale ist kurz weg und meldet sich von selbst zurück. Vorher wurde automatisch ein Sicherheits-Backup des jetzigen Zustands gemacht.")
    } catch (e: any) {
      showAlert("Start fehlgeschlagen", String(e?.message || e))
    } finally {
      setBusy(null)
    }
  }

  async function backupNow() {
    setBackupBusy(true)
    try {
      const r = await api<{ ok: boolean; snapshot?: string; error?: string }>("/api/system/backup", { method: "POST" })
      if (r.ok) showAlert("Gesichert", `Snapshot ${r.snapshot} wurde angelegt.`)
      else showAlert("Backup fehlgeschlagen", r.error || "Unbekannter Fehler")
      qc.invalidateQueries({ queryKey: qk.zeitmaschine })
    } catch (e: any) {
      showAlert("Backup fehlgeschlagen", String(e?.message || e))
    } finally {
      setBackupBusy(false)
    }
  }

  return (
    <section className="space-y-3">
      <div className="flex items-center justify-between">
        <p className="flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/60">
          <Archive className="h-3.5 w-3.5" /> Zeitmaschine — gesicherte Stände
        </p>
        <button onClick={backupNow} disabled={backupBusy || !data?.available}
          className="flex h-8 items-center gap-1.5 rounded-lg border border-border/60 bg-card/45 px-2.5 text-[11px] font-semibold text-muted-foreground hover:text-foreground hover:border-primary/40 transition-all cursor-pointer disabled:opacity-50">
          {backupBusy ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Archive className="h-3.5 w-3.5" />} Jetzt sichern
        </button>
      </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 Snapshots liegen auf der Box — im lokalen Dev-Modus nicht verfügbar.
        </div>
      )}

      {data?.available && backups.length === 0 && (
        <div className="rounded-2xl border border-dashed border-border/60 bg-card/20 p-5 text-center text-xs text-muted-foreground">
          Noch keine Snapshots. Das nächtliche Backup (03:30) legt sie automatisch an — oder „Jetzt sichern".
        </div>
      )}

      {shown.length > 0 && (
        <div className="grid gap-2 sm:grid-cols-2">
          {shown.map((s, idx) => (
            <div key={s.file} className="flex items-center justify-between gap-3 rounded-xl border border-border/50 bg-card/40 p-3">
              <div className="min-w-0">
                <p className="text-xs font-semibold text-foreground">
                  {fmtSnap(s)} {idx === 0 && <span className="ml-1 rounded bg-emerald-500/10 px-1.5 py-0.5 text-[9px] font-bold text-emerald-300">neuester</span>}
                </p>
                <p className="font-mono text-[10px] text-muted-foreground/70 truncate" title={s.file}>{s.size_mb.toLocaleString("de-DE")} MB · {s.file}</p>
              </div>
              <button
                disabled={busy !== null}
                onClick={() =>
                  showConfirm("Wirklich zu diesem Stand zurück?",
                    `Die Box wird auf den Snapshot vom ${fmtSnap(s)} zurückgesetzt (Gedächtnis, Hermes-Config, Modell-Router). Der JETZIGE Zustand wird vorher automatisch gesichert — der Schritt ist also umkehrbar. Die Dienste starten neu, die Zentrale ist kurz weg.`,
                    () => restore(s))}
                className="flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-amber-500/40 bg-amber-500/10 px-2.5 text-[10px] font-bold uppercase tracking-wide text-amber-300 transition-all hover:bg-amber-500/20 cursor-pointer disabled:opacity-50">
                {busy === s.file ? <Loader2 className="h-3 w-3 animate-spin" /> : <RotateCcw className="h-3 w-3" />} Zurück
              </button>
            </div>
          ))}
        </div>
      )}
      {backups.length > 4 && !showAll && (
        <button onClick={() => setShowAll(true)} className="text-[11px] text-muted-foreground underline hover:text-foreground">
          Alle {backups.length} Snapshots anzeigen
        </button>
      )}
      {dialogElement}
    </section>
  )
}
