import Link from "next/link";
import { getFormatter } from "next-intl/server";
import { Pencil, Plus, Trash2 } from "lucide-react";
import type {
  ClassificationClass,
  CryptoEntry,
  HandbookTopic,
  HandlingAspect,
  HandlingRule,
  PolicyDocument,
  PolicyVariable,
  RiskDamageDimension,
  RiskEwLevel,
  RiskMatrixClass,
} from "@prisma/client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Pill } from "@/components/mockup-ui";
import { isExpired, isExpiring } from "@/lib/supplier";
import { applyProtection, buildContext, renderPolicyHtml, resolveLink } from "@/lib/policy-render";
import {
  addClassificationClass,
  addCryptoEntry,
  addHandlingAspect,
  deleteCryptoEntry,
  updateCryptoEntry,
  updateDamageDimension,
  updateEwLevel,
  updateHandlingRule,
  updateRiskClass,
} from "@/server/actions/policies";

const TONE_HEX: Record<string, string> = { ok: "#2ea86b", warn: "#e3b427", orange: "#e2802e", risk: "#d63c5e" };

export interface RegisterData {
  crypto?: CryptoEntry[];
  classes?: ClassificationClass[];
  aspects?: HandlingAspect[];
  rules?: HandlingRule[];
  riskClasses?: RiskMatrixClass[];
  ewLevels?: RiskEwLevel[];
  damage?: RiskDamageDimension[];
  handbook?: HandbookTopic[];
  variables?: PolicyVariable[];
}

/** Inhalt der verwalteten Register (§7b) und des Anwender-Handbuchs (§9.7) — auf eigener Seite. */
export async function PolicyRegisterView({
  doc,
  data,
  canWrite,
}: {
  doc: PolicyDocument;
  data: RegisterData;
  canWrite: boolean;
}) {
  return (
    <div>
      {doc.code === "CRYPTO" && <CryptoRegister entries={data.crypto ?? []} canWrite={canWrite} />}
      {doc.code === "CLASSIFICATION" && (
        <ClassificationMatrix classes={data.classes ?? []} aspects={data.aspects ?? []} rules={data.rules ?? []} canWrite={canWrite} />
      )}
      {doc.code === "RISKMATRIX" && (
        <RiskMatrix classes={data.riskClasses ?? []} ew={data.ewLevels ?? []} damage={data.damage ?? []} canWrite={canWrite} />
      )}
      {doc.code === "HANDBUCH" && <Handbook topics={data.handbook ?? []} variables={data.variables ?? []} />}
    </div>
  );
}

/* ─────────────── Krypto-Register ─────────────── */

async function CryptoRegister({ entries, canWrite }: { entries: CryptoEntry[]; canWrite: boolean }) {
  const fmt = await getFormatter();
  const date = (d: Date | null) => (d ? fmt.dateTime(d, { dateStyle: "medium" }) : "—");
  const expiring = entries.filter((e) => isExpiring(e.ablaufdatum) || isExpired(e.ablaufdatum)).length;

  return (
    <div>
      <div className="mb-3 flex items-center justify-between gap-2">
        <p className="text-[12.5px] text-muted-foreground">
          Eingesetzte Verschlüsselung mit Ablaufüberwachung.{" "}
          {expiring > 0 && <span className="font-semibold text-[var(--warn)]">{expiring} laufen bald ab / abgelaufen.</span>}
        </p>
        {canWrite && (
          <details className="relative">
            <summary className="bg-grad-soft inline-flex h-8 cursor-pointer list-none items-center gap-1.5 rounded-lg px-2.5 font-heading text-sm font-semibold text-white select-none hover:opacity-90 [&::-webkit-details-marker]:hidden">
              <Plus className="size-4" /> Eintrag
            </summary>
            <form action={addCryptoEntry} className="shadow-card absolute right-0 z-10 mt-2 w-80 space-y-2 rounded-xl border bg-card p-3 text-sm">
              <Input name="dienst" required placeholder="Dienst" />
              <Input name="schluessel" required placeholder="Schlüssel" />
              <Input name="algorithmus" placeholder="Algorithmus / Länge" />
              <Input name="ablaufdatum" type="date" />
              <Input name="verantwortlich" placeholder="Verantwortlich" />
              <Input name="speicherort" placeholder="Speicherort" />
              <Input name="baselineRef" placeholder="Baseline (BL-CRY-…)" />
              <Button type="submit" variant="secondary" size="sm">Hinzufügen</Button>
            </form>
          </details>
        )}
      </div>
      <div className="rounded-xl border">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b bg-[var(--elevated)] text-[10.5px] tracking-[.04em] text-muted-foreground uppercase">
              <th className="p-2.5 text-left">Dienst</th>
              <th className="p-2.5 text-left">Schlüssel</th>
              <th className="p-2.5 text-left">Algorithmus</th>
              <th className="p-2.5 text-left">Ablauf</th>
              <th className="p-2.5 text-left">Verantwortlich</th>
              <th className="p-2.5 text-left">Baseline</th>
              {canWrite && <th className="p-2.5" />}
            </tr>
          </thead>
          <tbody>
            {entries.length === 0 && (
              <tr><td colSpan={7} className="p-6 text-center text-muted-foreground">Noch keine Einträge.</td></tr>
            )}
            {entries.map((e) => {
              const exp = isExpired(e.ablaufdatum);
              const soon = !exp && isExpiring(e.ablaufdatum);
              return (
                <tr key={e.id} className="border-b last:border-0">
                  <td className="p-2.5 font-medium">{e.dienst}</td>
                  <td className="p-2.5 text-muted-foreground">{e.schluessel}</td>
                  <td className="p-2.5 text-muted-foreground">{e.algorithmus ?? "—"}</td>
                  <td className="p-2.5">
                    <span className={exp ? "font-semibold text-[var(--risk)]" : soon ? "font-semibold text-[var(--warn)]" : "text-muted-foreground"}>
                      {date(e.ablaufdatum)}
                    </span>
                    {exp && <Pill tone="risk">abgelaufen</Pill>}
                    {soon && <Pill tone="warn">läuft ab</Pill>}
                  </td>
                  <td className="p-2.5 text-muted-foreground">{e.verantwortlich}</td>
                  <td className="p-2.5">{e.baselineRef ? <Pill tone="violet">{e.baselineRef}</Pill> : <span className="text-muted-foreground">—</span>}</td>
                  {canWrite && (
                    <td className="p-2.5">
                      <div className="flex items-center justify-end gap-1">
                        <details className="relative">
                          <summary className="grid size-7 cursor-pointer list-none place-items-center rounded-md text-muted-foreground hover:bg-muted [&::-webkit-details-marker]:hidden"><Pencil className="size-3.5" /></summary>
                          <form action={updateCryptoEntry.bind(null, e.id)} className="shadow-card absolute right-0 z-10 mt-2 w-72 space-y-2 rounded-xl border bg-card p-3 text-sm">
                            <Input name="dienst" required defaultValue={e.dienst} />
                            <Input name="schluessel" required defaultValue={e.schluessel} />
                            <Input name="algorithmus" defaultValue={e.algorithmus ?? ""} placeholder="Algorithmus" />
                            <Input name="ablaufdatum" type="date" defaultValue={e.ablaufdatum ? e.ablaufdatum.toISOString().slice(0, 10) : ""} />
                            <Input name="verantwortlich" defaultValue={e.verantwortlich} />
                            <Input name="speicherort" defaultValue={e.speicherort ?? ""} placeholder="Speicherort" />
                            <Input name="baselineRef" defaultValue={e.baselineRef ?? ""} placeholder="BL-CRY-…" />
                            <Button type="submit" variant="secondary" size="sm">Speichern</Button>
                          </form>
                        </details>
                        <form action={deleteCryptoEntry.bind(null, e.id)}>
                          <button type="submit" title="Löschen" className="grid size-7 place-items-center rounded-md text-muted-foreground hover:text-destructive"><Trash2 className="size-3.5" /></button>
                        </form>
                      </div>
                    </td>
                  )}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

/* ─────────────── Klassifizierungs-Handhabungsmatrix ─────────────── */

function ClassificationMatrix({
  classes, aspects, rules, canWrite,
}: { classes: ClassificationClass[]; aspects: HandlingAspect[]; rules: HandlingRule[]; canWrite: boolean }) {
  const ruleOf = (classId: string, aspectId: string) => rules.find((r) => r.classId === classId && r.aspectId === aspectId)?.text ?? "";
  return (
    <div>
      <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
        <p className="text-[12.5px] text-muted-foreground">Handhabungsregeln je Schutzklasse. Assets erben die Regeln aus ihrer Klasse.</p>
        {canWrite && (
          <div className="flex gap-2">
            <details className="relative">
              <summary className="inline-flex h-8 cursor-pointer list-none items-center gap-1.5 rounded-lg border px-2.5 text-[12.5px] font-semibold text-muted-foreground hover:text-foreground [&::-webkit-details-marker]:hidden"><Plus className="size-3.5" /> Aspekt</summary>
              <form action={addHandlingAspect} className="shadow-card absolute right-0 z-10 mt-2 w-72 space-y-2 rounded-xl border bg-card p-3 text-sm">
                <Input name="name" required placeholder="Aspekt (Zeile)" />
                <Input name="category" placeholder="Kategorie" />
                <Button type="submit" variant="secondary" size="sm">Hinzufügen</Button>
              </form>
            </details>
            <details className="relative">
              <summary className="inline-flex h-8 cursor-pointer list-none items-center gap-1.5 rounded-lg border px-2.5 text-[12.5px] font-semibold text-muted-foreground hover:text-foreground [&::-webkit-details-marker]:hidden"><Plus className="size-3.5" /> Schutzklasse</summary>
              <form action={addClassificationClass} className="shadow-card absolute right-0 z-10 mt-2 w-72 space-y-2 rounded-xl border bg-card p-3 text-sm">
                <Input name="name" required placeholder="Schutzklasse (Spalte)" />
                <Input name="description" placeholder="Beschreibung" />
                <Button type="submit" variant="secondary" size="sm">Hinzufügen</Button>
              </form>
            </details>
          </div>
        )}
      </div>
      <div className="overflow-x-auto rounded-xl border">
        <table className="w-full text-[12.5px]">
          <thead>
            <tr className="border-b bg-[var(--elevated)]">
              <th className="p-2.5 text-left text-[10.5px] tracking-[.04em] text-muted-foreground uppercase">Aspekt</th>
              {classes.map((c) => (
                <th key={c.id} className="min-w-40 p-2.5 text-left font-heading font-bold" title={c.description ?? ""}>{c.name}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {aspects.map((a) => (
              <tr key={a.id} className="border-b last:border-0 align-top">
                <td className="p-2.5 font-medium">{a.name}</td>
                {classes.map((c) => (
                  <td key={c.id} className="p-1.5">
                    {canWrite ? (
                      <details className="group">
                        <summary className="cursor-pointer list-none rounded-md px-2 py-1.5 hover:bg-muted/50 [&::-webkit-details-marker]:hidden">{ruleOf(c.id, a.id) || <span className="text-muted-foreground">—</span>}</summary>
                        <form action={updateHandlingRule.bind(null, c.id, a.id)} className="mt-1 flex gap-1">
                          <Input name="text" defaultValue={ruleOf(c.id, a.id)} className="h-8" />
                          <Button type="submit" variant="secondary" size="sm">OK</Button>
                        </form>
                      </details>
                    ) : (
                      <span className="px-2">{ruleOf(c.id, a.id) || "—"}</span>
                    )}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

/* ─────────────── Risiko-Bewertungsmatrix ─────────────── */

function RiskMatrix({
  classes, ew, damage, canWrite,
}: { classes: RiskMatrixClass[]; ew: RiskEwLevel[]; damage: RiskDamageDimension[]; canWrite: boolean }) {
  const sorted = [...classes].sort((a, b) => a.maxScore - b.maxScore);
  const classFor = (score: number) => sorted.find((c) => score <= c.maxScore) ?? sorted[sorted.length - 1];
  const rows = [4, 3, 2, 1]; // Schadensausmaß (oben = 4)
  const cols = [1, 2, 3, 4]; // Eintrittswahrscheinlichkeit

  return (
    <div className="space-y-5">
      {/* 4×4 Heatmap */}
      <section>
        <p className="mb-2 font-heading text-sm font-semibold">Bewertungsmatrix (Schadensausmaß × Eintrittswahrscheinlichkeit)</p>
        <div className="inline-block overflow-hidden rounded-xl border">
          <table className="text-center text-[12.5px]">
            <tbody>
              {rows.map((s) => (
                <tr key={s}>
                  <th className="bg-[var(--elevated)] px-3 py-2 text-muted-foreground">S {s}</th>
                  {cols.map((e) => {
                    const score = s * e;
                    const cls = classFor(score);
                    return (
                      <td key={e} className="px-4 py-2 font-bold text-white" style={{ background: TONE_HEX[cls?.tone] ?? "#555" }} title={`${cls?.name} (${score})`}>
                        {score}
                      </td>
                    );
                  })}
                </tr>
              ))}
              <tr>
                <th className="bg-[var(--elevated)] px-3 py-2" />
                {cols.map((e) => (
                  <th key={e} className="bg-[var(--elevated)] px-4 py-2 text-muted-foreground">EW {e}</th>
                ))}
              </tr>
            </tbody>
          </table>
        </div>
      </section>

      {/* Risikoklassen + Akzeptanzinstanz — inline editierbar */}
      <section>
        <p className="mb-2 font-heading text-sm font-semibold">Risikoklassen & Akzeptanz {canWrite && <span className="text-[11px] font-normal text-muted-foreground">· zum Bearbeiten auf eine Zeile klicken</span>}</p>
        <div className="rounded-xl border">
          <div className="grid grid-cols-[8rem_7rem_1fr] gap-x-3 border-b bg-[var(--elevated)] px-3 py-2 text-[10.5px] tracking-[.04em] text-muted-foreground uppercase">
            <span>Klasse</span><span>Bis Risikowert</span><span>Akzeptanzinstanz</span>
          </div>
          {sorted.map((c) => (
            canWrite ? (
              <details key={c.id} className="border-b last:border-0">
                <summary className="grid cursor-pointer grid-cols-[8rem_7rem_1fr] items-center gap-x-3 px-3 py-2.5 text-sm select-none hover:bg-muted/40 [&::-webkit-details-marker]:hidden">
                  <span><Pill tone={c.tone as "ok" | "warn" | "orange" | "risk"}>{c.name}</Pill></span>
                  <span className="font-medium">≤ {c.maxScore}</span>
                  <span className="flex items-center justify-between gap-2 text-muted-foreground">{c.acceptance}<Pencil className="size-3.5 shrink-0 opacity-60" /></span>
                </summary>
                <form action={updateRiskClass.bind(null, c.id)} className="grid gap-2 border-t bg-[var(--surface-soft)] p-3 sm:grid-cols-[8rem_7rem_1fr_auto]">
                  <Input name="name" required defaultValue={c.name} placeholder="Klasse" className="h-8" />
                  <Input name="maxScore" type="number" required defaultValue={c.maxScore} placeholder="≤ Wert" className="h-8" />
                  <Input name="acceptance" defaultValue={c.acceptance} placeholder="Akzeptanzinstanz" className="h-8" />
                  <Button type="submit" variant="secondary" size="sm">Speichern</Button>
                </form>
              </details>
            ) : (
              <div key={c.id} className="grid grid-cols-[8rem_7rem_1fr] items-center gap-x-3 border-b px-3 py-2.5 text-sm last:border-0">
                <span><Pill tone={c.tone as "ok" | "warn" | "orange" | "risk"}>{c.name}</Pill></span>
                <span className="font-medium">≤ {c.maxScore}</span>
                <span className="text-muted-foreground">{c.acceptance}</span>
              </div>
            )
          ))}
        </div>
      </section>

      {/* Eintrittswahrscheinlichkeit — inline editierbar */}
      <section>
        <p className="mb-2 font-heading text-sm font-semibold">Eintrittswahrscheinlichkeit</p>
        <div className="rounded-xl border">
          {[...ew].sort((a, b) => a.level - b.level).map((l) => (
            canWrite ? (
              <details key={l.id} className="border-b last:border-0">
                <summary className="flex cursor-pointer items-center justify-between gap-2 px-3 py-2 text-[12.5px] select-none hover:bg-muted/40 [&::-webkit-details-marker]:hidden">
                  <span><b>{l.level} · {l.label}</b> <span className="text-muted-foreground">— {l.definition}</span></span>
                  <Pencil className="size-3.5 shrink-0 opacity-60" />
                </summary>
                <form action={updateEwLevel.bind(null, l.id)} className="grid gap-2 border-t bg-[var(--surface-soft)] p-3 sm:grid-cols-[10rem_1fr_auto]">
                  <Input name="label" required defaultValue={l.label} placeholder="Bezeichnung" className="h-8" />
                  <Input name="definition" defaultValue={l.definition} placeholder="Definition" className="h-8" />
                  <Button type="submit" variant="secondary" size="sm">Speichern</Button>
                </form>
              </details>
            ) : (
              <div key={l.id} className="border-b px-3 py-2 text-[12.5px] last:border-0"><b>{l.level} · {l.label}</b> <span className="text-muted-foreground">— {l.definition}</span></div>
            )
          ))}
        </div>
      </section>

      {/* Schadenskategorien — inline editierbar */}
      <section>
        <p className="mb-2 font-heading text-sm font-semibold">Schadenskategorien</p>
        <div className="rounded-xl border">
          <div className="hidden grid-cols-[12rem_1fr_1fr_1fr_1fr] gap-x-3 border-b bg-[var(--elevated)] px-3 py-2 text-[10.5px] tracking-[.04em] text-muted-foreground uppercase sm:grid">
            <span>Dimension</span><span>1 Niedrig</span><span>2 Normal</span><span>3 Hoch</span><span>4 Sehr hoch</span>
          </div>
          {damage.map((d) => {
            const lv = d.levels as Record<string, string>;
            return canWrite ? (
              <details key={d.id} className="border-b last:border-0">
                <summary className="grid cursor-pointer grid-cols-1 items-center gap-x-3 px-3 py-2.5 text-[12px] select-none hover:bg-muted/40 sm:grid-cols-[12rem_1fr_1fr_1fr_1fr] [&::-webkit-details-marker]:hidden">
                  <span className="flex items-center justify-between gap-2 font-medium">{d.name}<Pencil className="size-3.5 shrink-0 opacity-60 sm:hidden" /></span>
                  <span className="text-muted-foreground">{lv["1"]}</span><span className="text-muted-foreground">{lv["2"]}</span><span className="text-muted-foreground">{lv["3"]}</span><span className="text-muted-foreground">{lv["4"]}</span>
                </summary>
                <form action={updateDamageDimension.bind(null, d.id)} className="grid gap-2 border-t bg-[var(--surface-soft)] p-3 sm:grid-cols-2">
                  <Input name="name" required defaultValue={d.name} placeholder="Dimension" className="h-8 sm:col-span-2" />
                  <Input name="l1" defaultValue={lv["1"]} placeholder="1 Niedrig" className="h-8" />
                  <Input name="l2" defaultValue={lv["2"]} placeholder="2 Normal" className="h-8" />
                  <Input name="l3" defaultValue={lv["3"]} placeholder="3 Hoch" className="h-8" />
                  <Input name="l4" defaultValue={lv["4"]} placeholder="4 Sehr hoch" className="h-8" />
                  <Button type="submit" variant="secondary" size="sm" className="sm:col-span-2">Speichern</Button>
                </form>
              </details>
            ) : (
              <div key={d.id} className="grid grid-cols-1 gap-x-3 border-b px-3 py-2.5 text-[12px] last:border-0 sm:grid-cols-[12rem_1fr_1fr_1fr_1fr]">
                <span className="font-medium">{d.name}</span>
                <span className="text-muted-foreground">{lv["1"]}</span><span className="text-muted-foreground">{lv["2"]}</span><span className="text-muted-foreground">{lv["3"]}</span><span className="text-muted-foreground">{lv["4"]}</span>
              </div>
            );
          })}
        </div>
      </section>
    </div>
  );
}

/* ─────────────── Anwender-Handbuch ─────────────── */

function Handbook({ topics, variables }: { topics: HandbookTopic[]; variables: PolicyVariable[] }) {
  const ctx = applyProtection(buildContext(variables));
  const cats = [...new Set(topics.map((t) => t.category))];
  return (
    <div className="space-y-5">
      <p className="text-[12.5px] text-muted-foreground">
        Kompakte Regeln für Mitarbeitende. Werte (z. B. Passwortlänge) stammen aus der zentralen Baseline und bleiben automatisch synchron.
      </p>
      {cats.map((cat) => (
        <section key={cat}>
          <p className="mb-2 font-heading text-sm font-semibold text-[var(--band-text)]">{cat}</p>
          <div className="space-y-3">
            {topics.filter((t) => t.category === cat).map((topic) => (
              <div key={topic.id} className="rounded-xl border border-l-[3px] border-l-[var(--primary)] bg-[var(--surface-soft)] p-4">
                <p className="font-heading text-[14px] font-bold">{topic.title}</p>
                <div className="policy-prose mt-1" dangerouslySetInnerHTML={{ __html: renderPolicyHtml(topic.bodyMd, ctx, { readMode: false }) }} />
                {topic.sourceRefs.length > 0 && (
                  <div className="mt-2 flex flex-wrap items-center gap-2 text-[12px] text-muted-foreground">
                    Details:
                    {topic.sourceRefs.map((ref) => {
                      const { href, label } = resolveLink(ref);
                      return (
                        <Link key={ref} href={href} className="font-semibold text-[var(--info)] hover:underline">{label} →</Link>
                      );
                    })}
                  </div>
                )}
              </div>
            ))}
          </div>
        </section>
      ))}
    </div>
  );
}
