"use client";
import { useEffect, useMemo, useState } from "react";
import {
  onderdeelCategorieLabels,
  voorstelPrioriteitLabels,
  onderdeelVoorbeeldtekst,
  sorteerVoorstellen,
  stelModelSamen,
  vulOnderdeelVoorbeeldPlatIn,
  vindOnderdeelTegenhanger,
  auditOnderdeel,
  auditModel,
  type AuditBevinding,
  type Modeldocument,
  type Modelonderdeel,
  type VoorstelPrioriteit,
  type Wijzigingsvoorstel,
  type ModeldocumentVoorstel,
} from "@/data/modeldocumenten";
import { kiesModelInTaal } from "@/lib/modeldocumenten/taalkeuze";
// Voorstellen-preview via de echte dossierketen (opdracht notaris 2026-07-11:
// "voorbeeld moet echte workflow volgen") — zelfde invulling als ModellenTab.
import { vulModelVoorbeeldInViaWorkflow } from "@/lib/modeldocumenten/voorbeeld-workflow";
import { VoorbeeldTweeKolommen } from "./VoorbeeldTweeKolommen";
import type { SyncResultaat } from "@/lib/hooks/useModeldocumentenStorage";

const GEBRUIKSLOG_TYPE_LABELS: Record<string, string> = {
  onbekend_modeldocument: "Onbekend modeldocument opgevraagd",
  onbekende_modelbrief: "Onbekende modelbrief opgevraagd",
  onbekende_rechtshandeling: "Onbekende rechtshandeling opgevraagd",
  genegeerd_facultatief_onderdeel: "Facultatief onderdeel kon niet geactiveerd worden",
};

interface GebruikslogEvent {
  type: string;
  waarde: string;
  tijdstip: string;
}

function GebruikslogPaneel() {
  const [events, setEvents] = useState<GebruikslogEvent[] | null>(null);
  const [fout, setFout] = useState<string | null>(null);

  useEffect(() => {
    let actief = true;
    fetch("/api/gebruikslog")
      .then((r) => r.json())
      .then((json) => {
        if (actief) setEvents(json.events ?? []);
      })
      .catch(() => {
        if (actief) setFout("Kon de gebruikslog niet laden.");
      });
    return () => {
      actief = false;
    };
  }, []);

  if (fout) return null;
  if (!events || events.length === 0) return null;

  const perWaarde = new Map<string, { type: string; aantal: number }>();
  for (const event of events) {
    const key = `${event.type}::${event.waarde}`;
    const bestaand = perWaarde.get(key);
    perWaarde.set(key, { type: event.type, aantal: (bestaand?.aantal ?? 0) + 1 });
  }
  const top = [...perWaarde.entries()]
    .sort((a, b) => b[1].aantal - a[1].aantal)
    .slice(0, 8);

  return (
    <div className="bg-amber-50 border border-amber-200 rounded-xl px-5 py-4">
      <p className="text-sm font-semibold text-amber-800">
        🔎 Bibliotheekgaten ({events.length} signa{events.length === 1 ? "al" : "len"})
      </p>
      <p className="text-xs text-amber-700 mt-1">
        AI-agenten liepen hierop vast — een aanwijzing voor een ontbrekend of onvolledig
        modeldocument/-brief.
      </p>
      <ul className="mt-2 space-y-1">
        {top.map(([key, { type, aantal }]) => {
          const waarde = key.slice(type.length + 2);
          return (
            <li key={key} className="text-xs text-amber-800 flex gap-2">
              <span className="font-mono bg-amber-100 px-1.5 py-0.5 rounded shrink-0">{aantal}×</span>
              <span>
                {GEBRUIKSLOG_TYPE_LABELS[type] ?? type}: <span className="font-mono">{waarde}</span>
              </span>
            </li>
          );
        })}
      </ul>
    </div>
  );
}


const PRIORITEIT_STIJL: Record<VoorstelPrioriteit, string> = {
  hoog: "bg-red-50 text-red-700 border-red-200",
  midden: "bg-amber-50 text-amber-700 border-amber-200",
  laag: "bg-slate-100 text-slate-600 border-slate-200",
};

const PRIORITEIT_VOLGORDE: Record<VoorstelPrioriteit, number> = { hoog: 0, midden: 1, laag: 2 };

// ── Verbeterkandidaten (AUT-S9): de ervaring van het kantoor omgezet naar
// gerangschikte kandidaten (frequentie × ernst × recentheid) via
// lib/dossier/verbeterlus.ts. Zuiver informatief — geen enkele kandidaat wordt
// hier automatisch ingediend; het kanaal bepaalt via welk bestaand mechanisme
// de notaris (of een agent) hem alsnog moet indienen.

type VerbeterKanaal = "bibliotheek" | "code" | "kennis";

interface VerbeterKandidaat {
  sleutel: string;
  kanaal: VerbeterKanaal;
  prioriteit: VoorstelPrioriteit;
  titel: string;
  omschrijving: string;
  score: number;
  signalen: { bron: string; soort: string; onderwerp: string }[];
}

const KANAAL_LABEL: Record<VerbeterKanaal, string> = {
  bibliotheek: "Bibliotheek",
  code: "Code",
  kennis: "Kennisbank",
};
const KANAAL_STIJL: Record<VerbeterKanaal, string> = {
  bibliotheek: "bg-violet-50 text-violet-700 border-violet-200",
  code: "bg-sky-50 text-sky-700 border-sky-200",
  kennis: "bg-emerald-50 text-emerald-700 border-emerald-200",
};
const KANAAL_ACTIE: Record<VerbeterKanaal, string> = {
  bibliotheek: "Indienen: wijzigingsvoorstel op de betrokken clausule (hierboven/hieronder in dit tabblad).",
  code: "Indienen: nieuw verbetervoorstel (module Verbetervoorstellen).",
  kennis: "Indienen: kennisbank-item (module Kennisbank).",
};

function VerbeterkandidatenPaneel() {
  const [kandidaten, setKandidaten] = useState<VerbeterKandidaat[] | null>(null);
  const [open, setOpen] = useState(false);

  useEffect(() => {
    let actief = true;
    fetch("/api/dossier/verbeterlus")
      .then((r) => r.json())
      .then((json) => {
        if (actief) setKandidaten(json.kandidaten ?? []);
      })
      .catch(() => {
        if (actief) setKandidaten([]);
      });
    return () => {
      actief = false;
    };
  }, []);

  if (!kandidaten || kandidaten.length === 0) return null;

  return (
    <div className="bg-indigo-50 border border-indigo-200 rounded-xl px-5 py-4">
      <button onClick={() => setOpen((o) => !o)} className="w-full flex items-center justify-between gap-3 text-left">
        <div>
          <p className="text-sm font-semibold text-indigo-800">
            💡 Verbeterkandidaten ({kandidaten.length})
          </p>
          <p className="text-xs text-indigo-700 mt-1">
            Uit de opgebouwde ervaring (gebruikslog + bibliotheek-audit), gerangschikt op
            frequentie × ernst × recentheid — geen enkele is al ingediend.
          </p>
        </div>
        <span className="text-indigo-400 text-sm shrink-0">{open ? "▴" : "▾"}</span>
      </button>
      {open && (
        <ul className="mt-3 space-y-2">
          {kandidaten.map((k) => (
            <li key={k.sleutel} className="text-xs bg-white border border-indigo-100 rounded-lg px-3 py-2">
              <div className="flex items-center gap-1.5 flex-wrap mb-1">
                <span className={`px-1.5 py-0.5 rounded border font-medium ${KANAAL_STIJL[k.kanaal]}`}>
                  {KANAAL_LABEL[k.kanaal]}
                </span>
                <span className={`px-1.5 py-0.5 rounded border font-medium ${PRIORITEIT_STIJL[k.prioriteit]}`}>
                  {voorstelPrioriteitLabels[k.prioriteit]}
                </span>
                <span className="text-slate-400 font-mono">score {k.score}</span>
              </div>
              <p className="text-slate-800 font-medium">{k.titel}</p>
              <p className="text-slate-600 mt-0.5">{k.omschrijving}</p>
              <p className="text-indigo-600 mt-1 italic">{KANAAL_ACTIE[k.kanaal]}</p>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

/** NL/FR ingevuld voorbeeld van een modelonderdeel-voorstel, met wijziging t.o.v. de bestaande clausule (indien van toepassing) gemarkeerd. */
/** Kwaliteitscontrole van een voorstel: dezelfde auditmotor als de CI-test, tegen de toekomstige bibliotheekstand. */
function AuditPaneel({ bevindingen }: { bevindingen: AuditBevinding[] }) {
  if (bevindingen.length === 0) {
    return (
      <p className="text-xs text-emerald-700 bg-emerald-50 border border-emerald-200 rounded-lg px-3 py-2">
        ✓ Kwaliteitscontrole: geen bevindingen.
      </p>
    );
  }
  return (
    <div>
      <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
        Kwaliteitscontrole ({bevindingen.length})
      </p>
      <ul className="space-y-1">
        {bevindingen.map((b, i) => (
          <li
            key={i}
            className={`text-xs rounded-lg px-3 py-1.5 border ${
              b.ernst === "fout"
                ? "bg-red-50 border-red-200 text-red-800"
                : "bg-amber-50 border-amber-200 text-amber-800"
            }`}
          >
            {b.ernst === "fout" ? "✕" : "⚠"} {b.omschrijving}
          </li>
        ))}
      </ul>
    </div>
  );
}

function ModelonderdeelVoorbeeldMetDiff({
  voorgesteld,
  huidig,
  alleOnderdelen,
}: {
  voorgesteld: Modelonderdeel;
  huidig?: Modelonderdeel;
  alleOnderdelen: Modelonderdeel[];
}) {
  const voorbeeld = useMemo(() => {
    const taalVoorstel = voorgesteld.taal === "fr" ? "fr" : "nl";
    const voorgesteldTekst = vulOnderdeelVoorbeeldPlatIn(voorgesteld);
    const huidigTekst = huidig ? vulOnderdeelVoorbeeldPlatIn(huidig) : undefined;
    const tegenhangerVanHuidig = huidig ? vindOnderdeelTegenhanger(huidig, alleOnderdelen) : undefined;
    const tegenhangerTekst = tegenhangerVanHuidig ? vulOnderdeelVoorbeeldPlatIn(tegenhangerVanHuidig) : undefined;
    return {
      nl: taalVoorstel === "nl" ? voorgesteldTekst : tegenhangerTekst,
      fr: taalVoorstel === "fr" ? voorgesteldTekst : tegenhangerTekst,
      nlVorige: taalVoorstel === "nl" ? huidigTekst : undefined,
      frVorige: taalVoorstel === "fr" ? huidigTekst : undefined,
    };
  }, [voorgesteld, huidig, alleOnderdelen]);

  return (
    <div>
      <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
        Ingevuld voorbeeld (NL/FR){huidig && " — wijzigingen t.o.v. de bestaande clausule gemarkeerd"}
      </p>
      <VoorbeeldTweeKolommen nl={voorbeeld.nl} fr={voorbeeld.fr} nlVorige={voorbeeld.nlVorige} frVorige={voorbeeld.frVorige} />
    </div>
  );
}

/** NL/FR ingevuld voorbeeld van een modeldocument-voorstel, met wijziging t.o.v. het bestaande model (indien van toepassing) gemarkeerd. */
function ModelVoorbeeldMetDiff({
  voorgesteld,
  huidig,
  onderdelenVoorPreview,
  alleOnderdelen,
  alleModellen,
}: {
  voorgesteld: Modeldocument;
  huidig?: Modeldocument;
  onderdelenVoorPreview: Modelonderdeel[];
  alleOnderdelen: Modelonderdeel[];
  alleModellen: Modeldocument[];
}) {
  const voorbeeld = useMemo(() => {
    const taalVoorstel = voorgesteld.taal === "fr" ? "fr" : "nl";
    const voorgesteldTekst = vulModelVoorbeeldInViaWorkflow(voorgesteld, onderdelenVoorPreview);
    const huidigTekst = huidig ? vulModelVoorbeeldInViaWorkflow(huidig, alleOnderdelen) : undefined;
    const anderetaal = taalVoorstel === "fr" ? "nl" : "fr";
    const tegenhangerResultaat = huidig ? kiesModelInTaal(huidig, anderetaal, alleModellen) : undefined;
    const tegenhanger = tegenhangerResultaat?.gewisseld ? tegenhangerResultaat.model : undefined;
    const tegenhangerTekst = tegenhanger ? vulModelVoorbeeldInViaWorkflow(tegenhanger, alleOnderdelen) : undefined;
    return {
      nl: taalVoorstel === "nl" ? voorgesteldTekst : tegenhangerTekst,
      fr: taalVoorstel === "fr" ? voorgesteldTekst : tegenhangerTekst,
      nlVorige: taalVoorstel === "nl" ? huidigTekst : undefined,
      frVorige: taalVoorstel === "fr" ? huidigTekst : undefined,
    };
  }, [voorgesteld, huidig, onderdelenVoorPreview, alleOnderdelen, alleModellen]);

  return (
    <div>
      <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
        Ingevuld voorbeeld (NL/FR){huidig && " — wijzigingen t.o.v. het bestaande model gemarkeerd"}
      </p>
      <VoorbeeldTweeKolommen nl={voorbeeld.nl} fr={voorbeeld.fr} nlVorige={voorbeeld.nlVorige} frVorige={voorbeeld.frVorige} />
    </div>
  );
}

export function ValiderenTab({
  voorstellen,
  modelVoorstellen,
  alleOnderdelen,
  alleModellen,
  keurGoed,
  wijsAf,
  keurModelGoed,
  wijsModelAf,
  synchroniseer,
}: {
  voorstellen: Wijzigingsvoorstel[];
  modelVoorstellen: ModeldocumentVoorstel[];
  alleOnderdelen: Modelonderdeel[];
  alleModellen: Modeldocument[];
  keurGoed: (v: Wijzigingsvoorstel) => Promise<void>;
  wijsAf: (id: string) => Promise<void>;
  keurModelGoed: (v: ModeldocumentVoorstel) => Promise<void>;
  wijsModelAf: (id: string) => Promise<void>;
  synchroniseer: () => Promise<SyncResultaat>;
}) {
  const [openId, setOpenId] = useState<string | null>(null);
  const [bezigId, setBezigId] = useState<string | null>(null);
  const [bezigMetSync, setBezigMetSync] = useState(false);
  const [syncBericht, setSyncBericht] = useState<string | null>(null);

  const gesorteerd = useMemo(() => sorteerVoorstellen(voorstellen), [voorstellen]);
  const gesorteerdeModellen = useMemo(
    () =>
      [...modelVoorstellen].sort((a, b) => {
        const prio = PRIORITEIT_VOLGORDE[a.prioriteit] - PRIORITEIT_VOLGORDE[b.prioriteit];
        return prio !== 0 ? prio : a.datum.localeCompare(b.datum);
      }),
    [modelVoorstellen]
  );

  const totaal = gesorteerd.length + gesorteerdeModellen.length;

  async function doeSync() {
    setBezigMetSync(true);
    setSyncBericht(null);
    try {
      const r = await synchroniseer();
      if (r.fout) {
        setSyncBericht(`Synchronisatie mislukt: ${r.fout}`);
      } else {
        const totaalNieuw = r.onderdeelVoorstellen + r.modelVoorstellen;
        setSyncBericht(
          totaalNieuw === 0
            ? "Geen nieuwe voorstellen in de serverwachtrij."
            : `${totaalNieuw} nieuw${totaalNieuw === 1 ? " voorstel" : "e voorstellen"} opgehaald ` +
                `(${r.modelVoorstellen} model${r.modelVoorstellen === 1 ? "" : "len"}, ` +
                `${r.onderdeelVoorstellen} onderde${r.onderdeelVoorstellen === 1 ? "el" : "len"}).`
        );
      }
    } finally {
      setBezigMetSync(false);
    }
  }

  async function beslis(voorstel: Wijzigingsvoorstel, actie: "goedkeuren" | "afwijzen") {
    setBezigId(voorstel.id);
    try {
      if (actie === "goedkeuren") await keurGoed(voorstel);
      else await wijsAf(voorstel.id);
    } finally {
      setBezigId(null);
    }
  }

  async function beslisModel(voorstel: ModeldocumentVoorstel, actie: "goedkeuren" | "afwijzen") {
    setBezigId(voorstel.id);
    try {
      if (actie === "goedkeuren") await keurModelGoed(voorstel);
      else await wijsModelAf(voorstel.id);
    } finally {
      setBezigId(null);
    }
  }

  return (
    <div className="space-y-4">
      <GebruikslogPaneel />
      <VerbeterkandidatenPaneel />
      <div className="flex items-center justify-between gap-3 flex-wrap">
        <p className="text-sm text-slate-500">
          {totaal === 0
            ? "Geen openstaande voorstellen."
            : `${totaal} openstaand${totaal === 1 ? " voorstel" : "e voorstellen"}, gesorteerd op prioriteit. ` +
              "Goedkeuren neemt de voorgestelde tekst over in de bibliotheek; afwijzen verwijdert het voorstel."}
        </p>
        <button
          onClick={doeSync}
          disabled={bezigMetSync}
          title="Haal voorstellen op die via de MCP-server / API door een AI-agent zijn ingediend"
          className="text-sm px-4 py-2 rounded-lg font-medium border border-brand-300 text-brand-700 hover:bg-brand-50 disabled:opacity-50 shrink-0"
        >
          {bezigMetSync ? "⏳ Synchroniseren…" : "↻ Synchroniseer met server"}
        </button>
      </div>

      {syncBericht && (
        <p className="text-xs text-slate-500 bg-slate-50 border border-slate-200 rounded-lg px-3 py-2">
          {syncBericht}
        </p>
      )}

      {totaal === 0 && (
        <p className="text-sm text-slate-400 py-8 text-center">
          Geen openstaande voorstellen. Dien een voorstel in via &ldquo;Stel wijziging voor ter
          validatie&rdquo; (tabblad Modelonderdelen), &ldquo;Dien in als voorstel ter
          validatie&rdquo; (tabblad Verrijken), of laat een AI-agent er een indienen via de
          MCP-server en klik op &ldquo;Synchroniseer met server&rdquo;.
        </p>
      )}

      {/* Voorstellen voor volledige modeldocumenten */}
      {gesorteerdeModellen.map((v) => {
        const open = openId === v.id;
        const huidig = v.modelId ? alleModellen.find((m) => m.id === v.modelId) : undefined;
        const onderdelenVoorPreview = [...alleOnderdelen, ...v.nieuweOnderdelen];
        return (
          <div key={v.id} className="bg-white border border-brand-200 rounded-xl shadow-sm overflow-hidden">
            <button onClick={() => setOpenId(open ? null : v.id)} className="w-full text-left px-5 py-3 flex items-start gap-3">
              <span className={`text-xs px-2 py-0.5 rounded border font-medium shrink-0 ${PRIORITEIT_STIJL[v.prioriteit]}`}>
                {voorstelPrioriteitLabels[v.prioriteit]}
              </span>
              <div className="flex-1">
                <p className="text-sm font-semibold text-slate-800">
                  <span className="text-xs bg-brand-100 text-brand-700 px-1.5 py-0.5 rounded mr-2">Modeldocument</span>
                  {v.titel}
                </p>
                <p className="text-xs text-slate-400 mt-0.5">
                  {huidig ? `Wijziging van model: ${huidig.titel}` : "Nieuw modeldocument"} ·{" "}
                  {v.voorgesteldModel.akteType} · {v.voorgesteldModel.structuur.length} onderde
                  {v.voorgesteldModel.structuur.length === 1 ? "el" : "len"}
                  {v.nieuweOnderdelen.length > 0 && ` · ${v.nieuweOnderdelen.length} nieuw`} · {v.datum}
                  {v.bron && ` · Bron: ${v.bron}`}
                </p>
                {v.omschrijving && <p className="text-sm text-slate-600 mt-1">{v.omschrijving}</p>}
              </div>
              <span className="text-slate-400 text-sm shrink-0">{open ? "▴" : "▾"}</span>
            </button>

            {open && (
              <div className="border-t border-slate-100 px-5 py-4 space-y-4">
                {v.nieuweOnderdelen.length > 0 && (
                  <div>
                    <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
                      Nieuwe onderdelen ({v.nieuweOnderdelen.length})
                    </p>
                    <div className="flex flex-wrap gap-1.5">
                      {v.nieuweOnderdelen.map((o) => (
                        <span key={o.id} className="text-xs bg-amber-50 text-amber-700 px-2 py-0.5 rounded border border-amber-200">
                          {o.titel}
                        </span>
                      ))}
                    </div>
                  </div>
                )}
                <div>
                  <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
                    Samengesteld model (structuur)
                  </p>
                  <pre className="text-xs text-slate-700 whitespace-pre-wrap font-mono leading-relaxed p-4 bg-emerald-50 rounded-lg max-h-80 overflow-y-auto">
                    {stelModelSamen(v.voorgesteldModel, onderdelenVoorPreview)}
                  </pre>
                </div>
                <ModelVoorbeeldMetDiff
                  voorgesteld={v.voorgesteldModel}
                  huidig={huidig}
                  onderdelenVoorPreview={onderdelenVoorPreview}
                  alleOnderdelen={alleOnderdelen}
                  alleModellen={alleModellen}
                />
                <AuditPaneel
                  bevindingen={[
                    ...auditModel(v.voorgesteldModel, onderdelenVoorPreview, alleModellen),
                    ...v.nieuweOnderdelen.flatMap((o) => auditOnderdeel(o, onderdelenVoorPreview)),
                  ]}
                />
              </div>
            )}

            <div className="border-t border-slate-100 px-5 py-3 flex gap-2">
              <button
                onClick={() => beslisModel(v, "goedkeuren")}
                disabled={bezigId === v.id}
                className="text-sm px-4 py-2 rounded-lg font-medium bg-emerald-600 text-white hover:bg-emerald-700 disabled:bg-slate-300"
              >
                ✓ Goedkeuren (model + onderdelen overnemen)
              </button>
              <button
                onClick={() => beslisModel(v, "afwijzen")}
                disabled={bezigId === v.id}
                className="text-sm px-4 py-2 rounded-lg border border-red-200 text-red-600 hover:bg-red-50 disabled:opacity-50"
              >
                ✕ Afwijzen
              </button>
            </div>
          </div>
        );
      })}

      {/* Voorstellen voor modelonderdelen (clausules) */}
      {gesorteerd.map((v) => {
        const huidig = v.onderdeelId ? alleOnderdelen.find((o) => o.id === v.onderdeelId) : undefined;
        const open = openId === v.id;
        return (
          <div key={v.id} className="bg-white border border-slate-200 rounded-xl shadow-sm overflow-hidden">
            <button onClick={() => setOpenId(open ? null : v.id)} className="w-full text-left px-5 py-3 flex items-start gap-3">
              <span className={`text-xs px-2 py-0.5 rounded border font-medium shrink-0 ${PRIORITEIT_STIJL[v.prioriteit]}`}>
                {voorstelPrioriteitLabels[v.prioriteit]}
              </span>
              <div className="flex-1">
                <p className="text-sm font-semibold text-slate-800">{v.titel}</p>
                <p className="text-xs text-slate-400 mt-0.5">
                  {huidig ? `Wijziging van: ${huidig.titel}` : "Nieuw modelonderdeel"} ·{" "}
                  {onderdeelCategorieLabels[v.voorgesteldOnderdeel.categorie]} · {v.datum}
                  {v.bron && ` · Bron: ${v.bron}`}
                </p>
                {v.omschrijving && <p className="text-sm text-slate-600 mt-1">{v.omschrijving}</p>}
              </div>
              <span className="text-slate-400 text-sm shrink-0">{open ? "▴" : "▾"}</span>
            </button>

            {open && (
              <div className="border-t border-slate-100 px-5 py-4 space-y-4">
                {huidig && (
                  <div>
                    <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
                      Huidige tekst (v{huidig.versie})
                    </p>
                    <pre className="text-xs text-slate-700 whitespace-pre-wrap font-mono leading-relaxed p-4 bg-slate-50 rounded-lg max-h-64 overflow-y-auto">
                      {onderdeelVoorbeeldtekst(huidig) || "(geen basistekst)"}
                    </pre>
                  </div>
                )}
                <div>
                  <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
                    Voorgestelde tekst (v{v.voorgesteldOnderdeel.versie})
                  </p>
                  <pre className="text-xs text-slate-700 whitespace-pre-wrap font-mono leading-relaxed p-4 bg-emerald-50 rounded-lg max-h-64 overflow-y-auto">
                    {onderdeelVoorbeeldtekst(v.voorgesteldOnderdeel) || "(geen basistekst)"}
                  </pre>
                </div>
                <ModelonderdeelVoorbeeldMetDiff
                  voorgesteld={v.voorgesteldOnderdeel}
                  huidig={huidig}
                  alleOnderdelen={alleOnderdelen}
                />
                <AuditPaneel
                  bevindingen={auditOnderdeel(v.voorgesteldOnderdeel, [
                    ...alleOnderdelen.filter((o) => o.id !== v.voorgesteldOnderdeel.id),
                    v.voorgesteldOnderdeel,
                  ])}
                />
                <div>
                  <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1.5">
                    Toepasbaar in
                  </p>
                  <div className="flex flex-wrap gap-1.5">
                    {v.voorgesteldOnderdeel.toepasbaarOp.map((t) => (
                      <span key={t} className="text-xs bg-emerald-50 text-emerald-700 px-2 py-0.5 rounded">
                        {t}
                      </span>
                    ))}
                  </div>
                </div>
              </div>
            )}

            <div className="border-t border-slate-100 px-5 py-3 flex gap-2">
              <button
                onClick={() => beslis(v, "goedkeuren")}
                disabled={bezigId === v.id}
                className="text-sm px-4 py-2 rounded-lg font-medium bg-emerald-600 text-white hover:bg-emerald-700 disabled:bg-slate-300"
              >
                ✓ Goedkeuren
              </button>
              <button
                onClick={() => beslis(v, "afwijzen")}
                disabled={bezigId === v.id}
                className="text-sm px-4 py-2 rounded-lg border border-red-200 text-red-600 hover:bg-red-50 disabled:opacity-50"
              >
                ✕ Afwijzen
              </button>
            </div>
          </div>
        );
      })}
    </div>
  );
}
