"use client";
import { useMemo, useState } from "react";
import Link from "next/link";
import {
  hoofdthemaLabels,
  documentSoortLabels,
  documentAard,
  stelModelSamen,
  verzamelParameters,
  genereerDocument,
  standaardKeuzes,
  genereerVoorbeeldwaarden,
  bouwParameterCatalogus,
  type DocumentSoort,
  type Hoofdthema,
  type Modeldocument,
  type Modelonderdeel,
} from "@/data/modeldocumenten";
import { kiesModelInTaal } from "@/lib/modeldocumenten/taalkeuze";
import { VOORBEELDSETS, voorbeeldSetOpId, genereerVoorbeeldFinaal } from "@/lib/modeldocumenten/voorbeeldsets";
import { voorbeeldWorkflowInvulling } from "@/lib/modeldocumenten/voorbeeld-workflow";
import {
  groepeerPerRechtshandeling,
  koppelModelParen,
  onvertaaldeClausules,
} from "@/data/modeldocumenten/rechtshandeling";

// Kleurconventie gedeeld met OnderdelenNetwerk.tsx (blauw = akte, oranje = onderhands).
const AARD_KLEUR: Record<"akte" | "onderhands", string> = {
  akte: "#2563eb",
  onderhands: "#ea580c",
};
import { ModelEditor } from "./ModelEditor";
import { InvulView } from "./InvulView";
import { StructuurLijst } from "./StructuurLijst";
import { VoorbeeldTweeKolommen } from "./VoorbeeldTweeKolommen";
import { useMeervoudigeSelectie } from "@/lib/hooks/useMeervoudigeSelectie";

export function ModellenTab({
  alleModellen,
  alleOnderdelen,
  slaOp,
  verwijder,
  startInvulModel,
  startWaarden,
  startDossierLabel,
  startPartijHerhalingen,
  startKeuzes,
}: {
  alleModellen: Modeldocument[];
  alleOnderdelen: Modelonderdeel[];
  slaOp: (m: Modeldocument) => Promise<void>;
  verwijder: (id: string) => Promise<void>;
  /** Model dat bij het openen meteen in de InvulView moet worden geopend (dossier-handoff). */
  startInvulModel?: Modeldocument | null;
  /** Voorgevulde parameterwaarden voor de InvulView (dossier-handoff). */
  startWaarden?: Record<string, string>;
  /** Korte omschrijving van het brondossier voor weergave in de InvulView. */
  startDossierLabel?: string;
  /** Eén identificatie-herhaling per partij (dossier-handoff). */
  startPartijHerhalingen?: { label?: string; waarden: Record<string, string> }[];
  /** Uit het dossier afgeleide hypothese-/opname-keuzes (dossier-handoff). */
  startKeuzes?: { onderdeelId: string; variantId?: string; opnemen?: boolean }[];
}) {
  // Geen enkel model standaard opengeklapt (instructie notaris).
  const [openId, setOpenId] = useState<string | null>(null);
  const [editor, setEditor] = useState<{ basis?: Modeldocument; modus: "nieuw" | "bewerk" } | null>(null);
  const [invullen, setInvullen] = useState<Modeldocument | null>(startInvulModel ?? null);
  const [invulWaarden, setInvulWaarden] = useState<Record<string, string> | undefined>(startWaarden);
  const [invulDossierLabel, setInvulDossierLabel] = useState<string | undefined>(startDossierLabel);
  const [invulPartijHerhalingen, setInvulPartijHerhalingen] = useState<
    { label?: string; waarden: Record<string, string> }[] | undefined
  >(startPartijHerhalingen);
  const [invulKeuzes, setInvulKeuzes] = useState<
    { onderdeelId: string; variantId?: string; opnemen?: boolean }[] | undefined
  >(startKeuzes);
  const [zoek, setZoek] = useState("");
  const [thema, setThema] = useState<Hoofdthema | "alle">("alle");
  const [soort, setSoort] = useState<DocumentSoort | "alle">("alle");

  // Modellen als NL/FR-paar, gegroepeerd per rechtshandeling (akteType): één
  // kaart per paar; een paar blijft zichtbaar zodra één van beide talen matcht.
  const groepen = useMemo(() => {
    const term = zoek.trim().toLowerCase();
    const matcht = (m?: Modeldocument): boolean =>
      !!m &&
      (thema === "alle" || m.thema === thema) &&
      (soort === "alle" || (m.soort ?? "MOD") === soort) &&
      (!term || [m.titel, m.akteType, m.omschrijving, m.bron ?? ""].join(" ").toLowerCase().includes(term));
    return groepeerPerRechtshandeling(alleModellen)
      .map((g) => ({ ...g, paren: g.paren.filter((p) => matcht(p.nl) || matcht(p.fr)) }))
      .filter((g) => g.paren.length > 0);
  }, [alleModellen, zoek, thema, soort]);
  const zichtbareParen = useMemo(() => groepen.flatMap((g) => g.paren), [groepen]);
  const totaalParen = useMemo(() => koppelModelParen(alleModellen).length, [alleModellen]);

  // Enkel eigen modeldocumenten zijn rechtstreeks verwijderbaar (de
  // kantoorbibliotheek wordt nooit rechtstreeks gewijzigd, zie AGENTS.md).
  const verwijderbareIds = useMemo(
    () =>
      zichtbareParen
        .map((p) => (p.nl ?? p.fr)!)
        .filter((m) => m.isGebruiker)
        .map((m) => m.id),
    [zichtbareParen]
  );
  const { geselecteerd, klik, wisSelectie } = useMeervoudigeSelectie(verwijderbareIds);

  async function verwijderGeselecteerde() {
    const aantal = geselecteerd.size;
    if (!confirm(`${aantal} modeldocument${aantal > 1 ? "en" : ""} verwijderen?`)) return;
    for (const id of geselecteerd) await verwijder(id);
    wisSelectie();
  }

  if (invullen) {
    return (
      <InvulView
        model={invullen}
        alleOnderdelen={alleOnderdelen}
        onSluit={() => {
          setInvullen(null);
          setInvulWaarden(undefined);
          setInvulDossierLabel(undefined);
          setInvulPartijHerhalingen(undefined);
          setInvulKeuzes(undefined);
        }}
        initieleWaarden={invulWaarden}
        dossierLabel={invulDossierLabel}
        partijHerhalingen={invulPartijHerhalingen}
        keuzeOverrides={invulKeuzes}
      />
    );
  }

  if (editor) {
    return (
      <ModelEditor
        basis={editor.basis}
        modus={editor.modus}
        alleOnderdelen={alleOnderdelen}
        onAnnuleer={() => setEditor(null)}
        onBewaar={async (m) => {
          await slaOp(m);
          setEditor(null);
          setOpenId(m.id);
        }}
      />
    );
  }

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap gap-2 items-center">
        <input
          type="text"
          value={zoek}
          onChange={(e) => setZoek(e.target.value)}
          placeholder="Zoek in titel, akteType, omschrijving…"
          className="flex-1 min-w-48 text-sm border border-slate-300 rounded-lg px-3 py-2"
        />
        <select
          value={thema}
          onChange={(e) => setThema(e.target.value as Hoofdthema | "alle")}
          className="text-sm border border-slate-300 rounded-lg px-3 py-2 bg-white"
        >
          <option value="alle">Alle thema&apos;s</option>
          {Object.entries(hoofdthemaLabels).map(([id, label]) => (
            <option key={id} value={id}>
              {label}
            </option>
          ))}
        </select>
        <select
          value={soort}
          onChange={(e) => setSoort(e.target.value as DocumentSoort | "alle")}
          className="text-sm border border-slate-300 rounded-lg px-3 py-2 bg-white"
        >
          <option value="alle">Alle soorten</option>
          {Object.entries(documentSoortLabels).map(([id, label]) => (
            <option key={id} value={id}>
              {id} — {label}
            </option>
          ))}
        </select>
        <button
          onClick={() => setEditor({ modus: "nieuw" })}
          className="text-sm px-4 py-2 rounded-lg font-medium bg-brand-600 text-white hover:bg-brand-700"
        >
          + Nieuw modeldocument
        </button>
      </div>

      <p className="text-xs text-slate-400">
        {zichtbareParen.length} van {totaalParen} modellen (NL/FR-paren), per rechtshandeling ·{" "}
        <span className="text-emerald-700">groen = clausule nog te vertalen</span>
      </p>

      {geselecteerd.size > 0 && (
        <div className="flex items-center gap-3 bg-red-50 border border-red-200 rounded-lg px-4 py-2">
          <span className="text-sm text-red-800">
            {geselecteerd.size} modeldocument{geselecteerd.size > 1 ? "en" : ""} geselecteerd
          </span>
          <button
            onClick={verwijderGeselecteerde}
            className="text-xs px-3 py-1.5 rounded-lg bg-red-600 text-white hover:bg-red-700"
          >
            Verwijder geselecteerde
          </button>
          <button
            onClick={wisSelectie}
            className="text-xs px-3 py-1.5 rounded-lg border border-slate-300 text-slate-600 hover:border-slate-400"
          >
            Annuleer selectie
          </button>
        </div>
      )}

      {groepen.map((groep) => (
        <div key={groep.rechtshandeling}>
          <h3 className="text-xs font-semibold text-slate-500 uppercase tracking-wide mt-5 mb-2">
            {groep.rechtshandeling}{" "}
            <span className="text-slate-400 font-normal normal-case">({groep.paren.length})</span>
          </h3>
          <div className="space-y-3">
            {groep.paren.map((paar) => {
              const m = (paar.nl ?? paar.fr)!;
              return (
                <ModelKaart
                  key={m.id}
                  model={m}
                  alleOnderdelen={alleOnderdelen}
                  alleModellen={alleModellen}
                  open={openId === m.id}
                  onToggle={() => setOpenId(openId === m.id ? null : m.id)}
                  geselecteerd={geselecteerd.has(m.id)}
                  onSelectieKlik={
                    m.isGebruiker ? (e: React.MouseEvent) => klik(m.id, e) : undefined
                  }
                  onGebruik={() => {
                    setInvulWaarden(undefined);
                    setInvulDossierLabel(undefined);
                    setInvullen(m);
                  }}
                  onBewerk={() => setEditor({ basis: m, modus: "bewerk" })}
                  onDupliceer={() =>
                    setEditor({
                      modus: "nieuw",
                      basis: { ...m, id: crypto.randomUUID(), titel: `${m.titel} (kopie)`, isGebruiker: true },
                    })
                  }
                  onVerwijder={
                    m.isGebruiker
                      ? () => {
                          if (confirm(`Modeldocument "${m.titel}" verwijderen?`)) verwijder(m.id);
                        }
                      : undefined
                  }
                />
              );
            })}
          </div>
        </div>
      ))}
    </div>
  );
}

function ModelKaart({
  model,
  alleOnderdelen,
  alleModellen,
  open,
  onToggle,
  geselecteerd,
  onSelectieKlik,
  onGebruik,
  onBewerk,
  onDupliceer,
  onVerwijder,
}: {
  model: Modeldocument;
  alleOnderdelen: Modelonderdeel[];
  alleModellen: Modeldocument[];
  open: boolean;
  onToggle: () => void;
  geselecteerd?: boolean;
  onSelectieKlik?: (e: React.MouseEvent) => void;
  onGebruik: () => void;
  onBewerk: () => void;
  onDupliceer: () => void;
  onVerwijder?: () => void;
}) {
  const [toonStructuur, setToonStructuur] = useState(false);
  const [toonRuweTekst, setToonRuweTekst] = useState(false);
  // Gekozen voorbeeldset ("" = standaard: alle hypotheses ter keuze).
  const [voorbeeldSetId, setVoorbeeldSetId] = useState("");
  const [finaleDownloadBezig, setFinaleDownloadBezig] = useState(false);

  // Haalt de printklare finale als .docx op via de word-route (?voorbeeldset=)
  // en opent de kortstondige downloadlink uit de levering.
  async function downloadFinaleWord() {
    if (!voorbeeldSetId) return;
    setFinaleDownloadBezig(true);
    try {
      const res = await fetch(`/api/modeldocumenten/${model.id}/word?voorbeeldset=${encodeURIComponent(voorbeeldSetId)}`);
      const data = (await res.json()) as { downloadUrl?: string; fout?: string };
      if (data.downloadUrl) window.open(data.downloadUrl, "_blank");
      else alert(data.fout ?? "Download mislukt — geen downloadUrl in het antwoord.");
    } finally {
      setFinaleDownloadBezig(false);
    }
  }
  const [gekopieerd, setGekopieerd] = useState(false);
  const [overrides, setOverrides] = useState<Record<string, string>>({});
  const [huidigModelId, setHuidigModelId] = useState(model.id);
  // Nieuw model geopend: eerdere handmatige parameterwaarden horen niet meer bij dit model
  // (React-patroon: state bijstellen tijdens render i.p.v. via een effect, zie React-docs).
  if (model.id !== huidigModelId) {
    setHuidigModelId(model.id);
    setOverrides({});
  }
  const aard = useMemo(() => documentAard(model), [model]);

  const samengesteld = useMemo(
    () => (toonRuweTekst ? stelModelSamen(model, alleOnderdelen) : ""),
    [toonRuweTekst, model, alleOnderdelen]
  );

  const taalHuidig = model.taal === "fr" ? "fr" : "nl";
  const tegenhanger = useMemo(() => {
    const anderetaal = taalHuidig === "fr" ? "nl" : "fr";
    const resultaat = kiesModelInTaal(model, anderetaal, alleModellen);
    return resultaat.gewisseld ? resultaat.model : undefined;
  }, [model, taalHuidig, alleModellen]);

  const keuzes = useMemo(() => standaardKeuzes(model), [model]);
  const keuzesTegenhanger = useMemo(
    () => (tegenhanger ? standaardKeuzes(tegenhanger) : []),
    [tegenhanger]
  );

  // Nog te vertalen clausules in het FR-model (instructie notaris: groen).
  const frVoorOnvertaald = taalHuidig === "fr" ? model : tegenhanger;
  const onvertaald = useMemo(
    () => (frVoorOnvertaald ? onvertaaldeClausules(frVoorOnvertaald, alleOnderdelen) : []),
    [frVoorOnvertaald, alleOnderdelen]
  );
  // De getoonde structuur is die van `model` (meestal NL): strip het
  // -fr-achtervoegsel zodat de groene markering op de juiste rij valt.
  const nogTeVertalenIds = useMemo(
    () => new Set(onvertaald.map((id) => (taalHuidig === "fr" ? id : id.replace(/-fr$/, "")))),
    [onvertaald, taalHuidig]
  );

  const eigenParameterNamen = useMemo(
    () => verzamelParameters(model, alleOnderdelen, keuzes),
    [model, alleOnderdelen, keuzes]
  );
  const tegenhangerParameterNamen = useMemo(
    () => (tegenhanger ? verzamelParameters(tegenhanger, alleOnderdelen, keuzesTegenhanger) : []),
    [tegenhanger, alleOnderdelen, keuzesTegenhanger]
  );
  const alleParameterNamen = useMemo(
    () => [...new Set([...eigenParameterNamen, ...tegenhangerParameterNamen])].sort((a, b) => a.localeCompare(b)),
    [eigenParameterNamen, tegenhangerParameterNamen]
  );
  // Bibliotheekbrede omschrijving per parameternaam (mappings-catalogus), ook
  // wanneer de declaratie in een ander onderdeel leeft dan dit model gebruikt.
  const catalogus = useMemo(() => bouwParameterCatalogus(alleOnderdelen), [alleOnderdelen]);

  // Eén standaardwaardenset PER TAAL, over alle parameters (eigen + tegenhanger)
  // heen: zo krijgt de NL-tekst altijd NL-voorbeeldwaarden en de FR-tekst altijd
  // FR-voorbeeldwaarden, ook voor een parameternaam die in beide modellen
  // voorkomt (bv. {{bodem}} of {{gemeente}}) — die anders door de gedeelde,
  // taalneutrale `waarden`-dictionary zou lekken (Franse voorbeeldtekst in de
  // NL-kolom of omgekeerd).
  const standaardWaardenPerTaal = useMemo(() => {
    // Per taal enkel de parameters uit onderdelen in díé taal: eenzelfde
    // parameternaam kan zowel in het NL- als het FR-onderdeel voorkomen (bv.
    // "jaar_voluit"), elk met een eigen taalgebonden `voorbeeld` — meng die
    // bronnen niet, anders wint willekeurig de ene taal ook in de andere kolom.
    const nlParameters = alleOnderdelen.filter((o) => o.taal !== "fr").flatMap((o) => o.parameters);
    const frParameters = alleOnderdelen.filter((o) => o.taal === "fr").flatMap((o) => o.parameters);
    // Het voorbeeld volgt de ECHTE workflow (opdracht notaris 2026-07-11): de
    // waarden uit de demo-dossierketen (identiteitsblokken via de canonieke
    // clausule, kantoorgegevens, prijs/goed) winnen van de losse demo-patronen.
    const workflowNl = voorbeeldWorkflowInvulling(model.akteType, "nl", alleOnderdelen);
    const workflowFr = voorbeeldWorkflowInvulling(model.akteType, "fr", alleOnderdelen);
    return {
      nl: { ...genereerVoorbeeldwaarden(alleParameterNamen, nlParameters, "nl"), ...workflowNl.waarden },
      fr: { ...genereerVoorbeeldwaarden(alleParameterNamen, frParameters, "fr"), ...workflowFr.waarden },
      herhalingen: { nl: workflowNl.partijHerhalingen, fr: workflowFr.partijHerhalingen },
    };
  }, [alleOnderdelen, alleParameterNamen, model.akteType]);

  // De editeerbare waarden (invulveld "Voorbeeldwaarden aanpassen") tonen de
  // standaardwaarde in de hoofdtaal van dit model; een handmatige wijziging
  // (overrides) geldt identiek voor beide taalkolommen.
  const waarden = useMemo(
    () => ({ ...standaardWaardenPerTaal[taalHuidig], ...overrides }),
    [standaardWaardenPerTaal, taalHuidig, overrides]
  );

  const voorbeeld = useMemo(() => {
    const nlModel = taalHuidig === "fr" ? tegenhanger : model;
    const frModel = taalHuidig === "fr" ? model : tegenhanger;
    // Is er een voorbeeldset gekozen, dan tonen we de FINALE, printklare
    // ontwerpversie: hypotheses beslist, parameters ingevuld, markeringen weg.
    const set = voorbeeldSetId ? voorbeeldSetOpId(voorbeeldSetId) : undefined;
    if (set) {
      return {
        nl: nlModel ? genereerVoorbeeldFinaal(nlModel, alleOnderdelen, set) : undefined,
        fr: frModel ? genereerVoorbeeldFinaal(frModel, alleOnderdelen, set) : undefined,
      };
    }
    const nlKeuzes = taalHuidig === "fr" ? keuzesTegenhanger : keuzes;
    const frKeuzes = taalHuidig === "fr" ? keuzes : keuzesTegenhanger;
    const nlWaarden = { ...standaardWaardenPerTaal.nl, ...overrides };
    const frWaarden = { ...standaardWaardenPerTaal.fr, ...overrides };
    return {
      nl: nlModel ? genereerDocument(nlModel, alleOnderdelen, nlKeuzes, nlWaarden, standaardWaardenPerTaal.herhalingen.nl) : undefined,
      fr: frModel ? genereerDocument(frModel, alleOnderdelen, frKeuzes, frWaarden, standaardWaardenPerTaal.herhalingen.fr) : undefined,
    };
  }, [voorbeeldSetId, taalHuidig, tegenhanger, model, keuzesTegenhanger, keuzes, alleOnderdelen, standaardWaardenPerTaal, overrides]);

  function wijzigWaarde(naam: string, waarde: string) {
    setOverrides((v) => ({ ...v, [naam]: waarde }));
  }

  async function kopieer() {
    await navigator.clipboard.writeText(stelModelSamen(model, alleOnderdelen));
    setGekopieerd(true);
    setTimeout(() => setGekopieerd(false), 2000);
  }

  return (
    <div
      className={`bg-white border rounded-xl shadow-sm overflow-hidden ${
        geselecteerd ? "border-red-300 ring-1 ring-red-200" : "border-slate-200"
      }`}
    >
      <div className="w-full text-left px-5 py-3 flex items-center gap-3">
        {onSelectieKlik && (
          <input
            type="checkbox"
            checked={!!geselecteerd}
            onClick={(e) => {
              e.stopPropagation();
              onSelectieKlik(e);
            }}
            onChange={() => {}}
            title="Selecteer (Shift = bereik, Ctrl/Cmd = toevoegen)"
            className="shrink-0 size-4 accent-red-600"
          />
        )}
        <button onClick={onToggle} className="flex-1 flex items-center gap-3 text-left">
          <div className="flex-1">
            <div className="flex items-center gap-2">
              <p className="text-sm font-semibold text-slate-800">{model.titel}</p>
              <span
                className="text-[10px] font-medium uppercase tracking-wide px-1.5 py-0.5 rounded"
                style={{ color: AARD_KLEUR[aard], background: `${AARD_KLEUR[aard]}1a` }}
              >
                {aard === "akte" ? "Notariële akte" : "Onderhands document"}
              </span>
              {tegenhanger || taalHuidig === "fr" ? (
                onvertaald.length > 0 ? (
                  <span
                    title="De Franstalige spiegel hergebruikt deze clausules nog in het Nederlands (of ze dragen [TE VERTALEN]) — groen tot de vertaling er is."
                    className="text-[10px] font-medium uppercase tracking-wide px-1.5 py-0.5 rounded bg-emerald-100 text-emerald-800"
                  >
                    NL + FR · {onvertaald.length} nog te vertalen
                  </span>
                ) : (
                  <span className="text-[10px] font-medium uppercase tracking-wide px-1.5 py-0.5 rounded bg-slate-100 text-slate-500">
                    NL + FR
                  </span>
                )
              ) : (
                <span
                  title="Er bestaat nog geen Franstalige spiegel van dit model."
                  className="text-[10px] font-medium uppercase tracking-wide px-1.5 py-0.5 rounded bg-emerald-100 text-emerald-800"
                >
                  FR nog te maken
                </span>
              )}
            </div>
            <p className="text-xs text-slate-400 mt-0.5">
              {model.thema && `${hoofdthemaLabels[model.thema]} · `}
              {model.soort && model.soort !== "MOD" && `${model.soort} · `}
              {model.akteType} · v{model.versie} · {model.structuur.length} onderdelen
              {model.isGebruiker && " · eigen model"}
            </p>
          </div>
          <span className="text-slate-400 text-sm">{open ? "▴" : "▾"}</span>
        </button>
      </div>

      {open && (
        <div className="border-t border-slate-100 px-5 py-4 space-y-4">
          <p className="text-sm text-slate-600">{model.omschrijving}</p>

          <div className="flex flex-wrap gap-2 pt-1">
            <button
              onClick={onGebruik}
              className="text-sm px-4 py-2 rounded-lg font-medium bg-emerald-600 text-white hover:bg-emerald-700"
            >
              ✍️ Vul in & genereer
            </button>
            <button
              onClick={kopieer}
              className={`text-sm px-4 py-2 rounded-lg font-medium text-white ${
                gekopieerd ? "bg-emerald-600" : "bg-brand-600 hover:bg-brand-700"
              }`}
            >
              {gekopieerd ? "✓ Gekopieerd" : "📋 Kopieer volledige modeltekst"}
            </button>
            <button
              onClick={() => setToonStructuur((v) => !v)}
              className="text-sm px-4 py-2 rounded-lg border border-slate-300 text-slate-600 hover:border-brand-300"
            >
              {toonStructuur ? "Verberg structuur" : "Toon structuur"}
            </button>
            <button
              onClick={() => setToonRuweTekst((v) => !v)}
              className="text-sm px-4 py-2 rounded-lg border border-slate-300 text-slate-600 hover:border-brand-300"
            >
              {toonRuweTekst ? "Verberg ruwe modeltekst" : "Toon ruwe modeltekst"}
            </button>
            {!model.isGebruiker && (
              <Link
                href={`/modeldocumenten/${model.id}`}
                className="text-sm px-4 py-2 rounded-lg border border-slate-300 text-slate-600 hover:border-brand-300"
              >
                🔗 Webpagina
              </Link>
            )}
            <button
              onClick={onDupliceer}
              className="text-sm px-4 py-2 rounded-lg border border-slate-300 text-slate-600 hover:border-brand-300"
            >
              Dupliceer
            </button>
            {model.isGebruiker && (
              <button
                onClick={onBewerk}
                className="text-sm px-4 py-2 rounded-lg border border-slate-300 text-slate-600 hover:border-brand-300"
              >
                Bewerk
              </button>
            )}
            {onVerwijder && (
              <button
                onClick={onVerwijder}
                className="text-sm px-4 py-2 rounded-lg border border-red-200 text-red-600 hover:bg-red-50"
              >
                Verwijder
              </button>
            )}
          </div>

          {alleParameterNamen.length > 0 && (
            <div>
              <div className="flex items-center justify-between mb-2">
                <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide">
                  Voorbeeldwaarden aanpassen — de akte hieronder werkt live mee
                </p>
                {Object.keys(overrides).length > 0 && (
                  <button
                    onClick={() => setOverrides({})}
                    className="text-xs text-brand-700 hover:underline shrink-0"
                  >
                    Herstel voorbeeldwaarden
                  </button>
                )}
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2 max-h-64 overflow-y-auto p-3 bg-slate-50 rounded-lg border border-slate-200">
                {alleParameterNamen.map((naam) => {
                  const info = catalogus.get(naam);
                  return (
                    <label
                      key={naam}
                      title={info?.omschrijving}
                      className="text-xs text-slate-600 space-y-0.5 block"
                    >
                      <span className="font-mono text-brand-700">{"{{" + naam + "}}"}</span>
                      {info?.omschrijving && (
                        <span className="block text-[10px] text-slate-400 truncate">{info.omschrijving}</span>
                      )}
                      <input
                        type="text"
                        value={waarden[naam] ?? ""}
                        onChange={(e) => wijzigWaarde(naam, e.target.value)}
                        className="w-full text-xs border border-slate-300 rounded px-2 py-1 bg-white"
                      />
                    </label>
                  );
                })}
              </div>
            </div>
          )}

          <div>
            <div className="flex flex-wrap items-center justify-between gap-2 mb-2">
              <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide">
                {voorbeeldSetId
                  ? `Finale ontwerpversie — ${voorbeeldSetOpId(voorbeeldSetId)?.naam ?? ""} (printklaar)`
                  : "Voorbeeldakte (NL/FR) — live bijgewerkt"}
              </p>
              <label className="flex items-center gap-1.5 text-xs text-slate-600">
                Voorbeeldset:
                <select
                  value={voorbeeldSetId}
                  onChange={(e) => setVoorbeeldSetId(e.target.value)}
                  className="text-xs border border-slate-300 rounded px-2 py-1 bg-white"
                >
                  <option value="">Standaard — alle hypotheses ter keuze</option>
                  {VOORBEELDSETS.map((s) => (
                    <option key={s.id} value={s.id}>
                      {s.naam}
                    </option>
                  ))}
                </select>
              </label>
            </div>
            {voorbeeldSetId && (
              <div className="flex flex-wrap items-center justify-between gap-2 mb-2">
                <p className="text-[11px] text-slate-500">
                  {voorbeeldSetOpId(voorbeeldSetId)?.omschrijving} — de hypotheses zijn beslist en de gegevens fictief maar
                  realistisch ingevuld; deze versie is bij wijze van spreken klaar om af te printen en te tekenen.
                </p>
                <button
                  onClick={downloadFinaleWord}
                  disabled={finaleDownloadBezig}
                  className="text-xs px-3 py-1.5 rounded-lg border border-brand-300 text-brand-700 hover:bg-brand-50 disabled:opacity-50 shrink-0"
                >
                  {finaleDownloadBezig ? "Bezig…" : "⬇ Download printklare versie (.docx)"}
                </button>
              </div>
            )}
            <VoorbeeldTweeKolommen
              nl={voorbeeld.nl}
              fr={voorbeeld.fr}
              frOpmerking={
                !voorbeeldSetId && onvertaald.length > 0
                  ? `${onvertaald.length} clausule(s) nog niet vertaald — voorlopig in het Nederlands opgenomen; zie de groene markering in de structuur.`
                  : undefined
              }
            />
          </div>

          {toonStructuur && (
            <div>
              <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">Structuur</p>
              <StructuurLijst
                structuur={model.structuur}
                onderdelen={alleOnderdelen}
                nogTeVertalen={nogTeVertalenIds}
              />
            </div>
          )}

          {toonRuweTekst && (
            <pre className="text-xs text-slate-700 whitespace-pre-wrap font-mono leading-relaxed p-4 bg-slate-50 rounded-lg max-h-[32rem] overflow-y-auto">
              {samengesteld}
            </pre>
          )}

          {model.bron && <p className="text-xs text-slate-400">Bron: {model.bron}</p>}
        </div>
      )}
    </div>
  );
}
