"use client";
import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useParams, useRouter } from "next/navigation";
import { useDossierStorage } from "@/lib/hooks/useDossierStorage";
import { useModeldocumentenStorage } from "@/lib/hooks/useModeldocumentenStorage";
import { stelWerkdossierSamenAutonoom } from "@/lib/dossier/werkdossier";
import { bepaalDocumenttaal } from "@/lib/dossier/taal";
import { seedModellen, seedOnderdelen, combineerMetSeed } from "@/data/modeldocumenten";
import { seedBrieven, briefCategorieLabels } from "@/data/modelbrieven";
import { berekenOntbrekendeStukken, stukLabel } from "@/lib/dossier/afleiding";
import {
  maakVeld,
  isVerkoopType,
  isVerkoopDossier,
  heeftOnroerendGoedVelden,
  heeftOverdrachtsbelastingVelden,
  BRON_TYPES,
  DOSSIERTYPE_LABEL,
  DOSSIERSTATUS_LABEL,
  type BronType,
  type Dossier,
  type DossierRelatie,
  type DossierStatus,
  type Partij,
  type Tegenstrijdigheid,
} from "@/lib/dossier/types";
import {
  DOSSIER_RELATIES,
  RELATIE_LABEL,
  dossierKortLabel,
  kanKoppelen,
  koppelDossiers,
  koppelingOverzicht,
  ontkoppelDossiers,
  verwijderVerbrokenKoppeling,
} from "@/lib/dossier/koppeling";
import { berekenTegenstrijdigheden, maakVeldUitWaarnemingen, kiesPrimaireBron } from "@/lib/dossier/tegenstrijdigheden";
import { dossierVeldenUitIntake, vindJsonObject, voegIntakeVeldenSamen, voegAttestenSamen } from "@/lib/dossier/intake";
import { berekenAkteKostenOverzicht } from "@/data/ereloon";
import { rechtshandelingVoorAkteType } from "@/data/vastgoed-opzoekingen";
import { useGewest, gewestNaarCode } from "@/lib/context/gewest";
import { useKantoor } from "@/lib/hooks/useKantoor";
import { euro, parseBedrag } from "@/lib/format";
import {
  schrijfAktekostenHandoff,
  schrijfOntwerpakteHandoff,
  schrijfModelbriefHandoff,
  schrijfBelastingHandoff,
  schrijfSchenkingHandoff,
} from "@/lib/handoff";
import {
  dossierNaarParameterwaarden,
  dossierNaarPartijHerhalingen,
  dossierNaarKeuzes,
} from "@/lib/dossier/parameters";
import { dossierNaarModelbriefWaarden } from "@/lib/dossier/modelbriefParameters";
import { relatieLabels, type GoedeType, type Relatie } from "@/data/belastingen";
import { vindChecklistVoorAkteType } from "@/data/kennisbank-checklists";
import { DossierChecklist } from "@/components/dossier/DossierChecklist";

/** Label + toelichting per verkoopregime, gedeeld tussen de knoppen op dit formulier. */
const VERKOOPREGIME_LABEL: Record<NonNullable<Dossier["verkoopRegime"]>, string> = {
  gewoon: "Gewone verkoop",
  "wet-breyne": "Wet Breyne (te bouwen/in aanbouw)",
  lijfrente: "Lijfrente",
};
const VERKOOPREGIME_TOELICHTING: Partial<Record<NonNullable<Dossier["verkoopRegime"]>, string>> = {
  "wet-breyne":
    "Wet Breyne (9 juli 1971): termijnbetaling per bouwfase, prijsherziening, waarborgregeling en tienjarige aansprakelijkheid — stuurt naar het Breyne-model i.p.v. de gewone verkoop.",
  lijfrente:
    "Verkoop tegen lijfrente: bouquet + periodieke rente i.p.v. een vaste prijs, met een aleatoir karakter en doorgaans een voorbehouden genotsrecht voor de verkoper — stuurt naar het lijfrente-model i.p.v. de gewone verkoop.",
};

interface AttestFormulier {
  epcDatum: string; epcNummer: string; epcLabel: string; epcGeldig: string;
  bodemDatum: string; bodemInhoud: string;
  keuringOrg: string; keuringDatum: string; keuringConclusie: string;
  stbDatum: string; stbBestemming: string; stbVergunningen: string;
  asbestDatum: string; asbestNummer: string; asbestConclusie: string;
  pScore: string; gScore: string;
}

const LEEG_ATTEST: AttestFormulier = {
  epcDatum: "", epcNummer: "", epcLabel: "", epcGeldig: "",
  bodemDatum: "", bodemInhoud: "",
  keuringOrg: "", keuringDatum: "", keuringConclusie: "",
  stbDatum: "", stbBestemming: "", stbVergunningen: "",
  asbestDatum: "", asbestNummer: "", asbestConclusie: "",
  pScore: "", gScore: "",
};

/** Bouwt het Attesten-object uit het formulier; leeg → undefined (geen lege subobjecten). */
function bouwAttesten(f: AttestFormulier): Dossier["attesten"] {
  const leeg = (o: Record<string, string | undefined>) =>
    Object.fromEntries(Object.entries(o).filter(([, v]) => v && v.trim()));
  const epc = leeg({ datum: f.epcDatum, nummer: f.epcNummer, label: f.epcLabel, geldigTot: f.epcGeldig });
  const bodem = leeg({ datum: f.bodemDatum, inhoud: f.bodemInhoud });
  const keuring = leeg({ organisme: f.keuringOrg, datum: f.keuringDatum, conclusie: f.keuringConclusie });
  const stedenbouw = leeg({ datum: f.stbDatum, bestemming: f.stbBestemming, vergunningen: f.stbVergunningen });
  const asbest = leeg({ datum: f.asbestDatum, nummer: f.asbestNummer, conclusie: f.asbestConclusie });
  const overstroming = leeg({ pScore: f.pScore, gScore: f.gScore });
  const attesten: NonNullable<Dossier["attesten"]> = {};
  if (Object.keys(epc).length) attesten.epc = epc;
  if (Object.keys(bodem).length) attesten.bodem = bodem;
  if (Object.keys(keuring).length) attesten.elektrischeKeuring = keuring;
  if (Object.keys(stedenbouw).length) attesten.stedenbouw = stedenbouw;
  if (Object.keys(asbest).length) attesten.asbest = asbest;
  if (Object.keys(overstroming).length) attesten.overstroming = overstroming;
  return Object.keys(attesten).length ? attesten : undefined;
}

const STATUSSEN: DossierStatus[] = [
  "compromis-ontvangen",
  "opzoekingen-lopend",
  "ontwerp-in-opmaak",
  "ontwerp-verstuurd",
  "klaar-voor-akte",
  "verleden",
];

export default function DossierDetailPage() {
  const params = useParams<{ id: string }>();
  const router = useRouter();
  const { dossiers, geladen, slaDossier, verwijderDossier } = useDossierStorage();
  const dossier = dossiers.find((d) => d.id === params.id) ?? null;
  const { gewest } = useGewest();
  const { kantoor } = useKantoor();
  const modeldocumentenOpslag = useModeldocumentenStorage();
  const alleModellen = useMemo(
    () => [...seedModellen, ...modeldocumentenOpslag.gebruikersModellen],
    [modeldocumentenOpslag.gebruikersModellen]
  );
  const alleOnderdelen = useMemo(
    () => combineerMetSeed(seedOnderdelen, modeldocumentenOpslag.gebruikersOnderdelen),
    [modeldocumentenOpslag.gebruikersOnderdelen]
  );
  // Vandaag (ISO-datum) voor de termijnbewaking van de opvolgingspijler; één
  // keer bepaald per render zodat het werkdossier reproduceerbaar blijft.
  const vandaag = useMemo(() => new Date().toISOString().slice(0, 10), []);
  const werkdossier = useMemo(
    () =>
      dossier
        ? stelWerkdossierSamenAutonoom(
            dossier,
            { modellen: alleModellen, onderdelen: alleOnderdelen, brieven: seedBrieven },
            gewest,
            bepaalDocumenttaal(dossier, kantoor),
            kantoor,
            vandaag
          )
        : null,
    [dossier, alleModellen, alleOnderdelen, gewest, kantoor, vandaag]
  );
  const autonoom = werkdossier?.ontwerpakte ?? null;
  const modelmails = werkdossier?.modelmails ?? null;
  const opvolging = werkdossier?.opvolging ?? null;
  const registratiebelasting = werkdossier?.afrekening.registratiebelasting ?? null;
  const aktekostenKrediet = werkdossier?.afrekening.aktekostenKrediet ?? null;
  const forfaitaireAfrekening = werkdossier?.afrekening.forfaitaireAfrekening ?? null;
  const verkoopDossier = dossier ? isVerkoopType(dossier.dossiertype) : false;
  // Brug naar de opzoekingsmatrix: enkel wanneer het gedetecteerde akteType
  // ondubbelzinnig bij een matrix-rechtshandeling hoort (RECHTSHANDELING_PER_AKTETYPE).
  const opzoekingenHandeling = autonoom?.akteTypeKeuze.akteType
    ? rechtshandelingVoorAkteType(autonoom.akteTypeKeuze.akteType)
    : undefined;
  // Dossierspecifieke checklist: dezelfde kennisbankchecklist, afvinkstatus
  // per dossier bewaard in dossier.checklistVoortgang.
  const checklist = autonoom?.akteTypeKeuze.akteType
    ? vindChecklistVoorAkteType(autonoom.akteTypeKeuze.akteType)
    : undefined;
  // Brug naar de ereloonmodule voor de kredietakte (verkoop met krediet).
  const kredietBedrag =
    dossier && isVerkoopDossier(dossier) ? dossier.kredietofferte?.waarde.bedrag : undefined;
  const overzicht = useMemo(
    () =>
      dossier && dossier.prijs
        ? berekenAkteKostenOverzicht("verkoop", dossier.prijs.waarde, gewest, {
            extraLeveringskostenIds: dossier.stedenbouwInlichtingenOntvangen?.waarde ? ["lev-stedenbouw"] : [],
          })
        : null,
    [dossier, gewest]
  );
  const [bewerken, setBewerken] = useState(false);
  const [adres, setAdres] = useState("");
  const [prijs, setPrijs] = useState("");
  const [kadastraal, setKadastraal] = useState("");
  const [gemeente, setGemeente] = useState("");
  const [afdeling, setAfdeling] = useState("");
  const [hypLast, setHypLast] = useState("");
  const [burgerlijkeStaten, setBurgerlijkeStaten] = useState<(Partij["burgerlijkeStaat"] | "")[]>([]);
  const [geslachten, setGeslachten] = useState<(Partij["geslacht"] | "")[]>([]);
  const [huwelijken, setHuwelijken] = useState<{ echtgenoot: string; plaats: string; datum: string; stelsel: string }[]>([]);
  const [stedenbouwOntvangen, setStedenbouwOntvangen] = useState(false);
  const [belastbareWaarde, setBelastbareWaarde] = useState("");
  const [relatie, setRelatie] = useState<Relatie>("rechte_lijn_partner");
  const [goedType, setGoedType] = useState<GoedeType>("onroerend");
  const [andereGoederen, setAndereGoederen] = useState("");
  const [altBedrag, setAltBedrag] = useState("");
  const [altBron, setAltBron] = useState<BronType>("eigendomstitel");
  const [compromisdatum, setCompromisdatum] = useState("");
  const [voorschot, setVoorschot] = useState("");
  const [verkoopdoc, setVerkoopdoc] = useState<NonNullable<Dossier["verkoopdocument"]> | "">("");
  const [verkoopRegime, setVerkoopRegime] = useState<NonNullable<Dossier["verkoopRegime"]>>("gewoon");
  const [gebruik, setGebruik] = useState<NonNullable<Dossier["gebruik"]> | "">("");
  const [referentie, setReferentie] = useState("");
  const [att, setAtt] = useState<AttestFormulier>(LEEG_ATTEST);
  const [importTekst, setImportTekst] = useState("");
  const [importMelding, setImportMelding] = useState<string | null>(null);
  const [importFout, setImportFout] = useState<string | null>(null);
  const [koppelDoelId, setKoppelDoelId] = useState("");
  const [koppelRelatie, setKoppelRelatie] = useState<DossierRelatie>("verwant");

  useEffect(() => {
    if (!dossier) return;
    // eslint-disable-next-line react-hooks/set-state-in-effect -- bestaand, bewust opslag-synchronisatiepatroon (IndexedDB/localStorage -> formulierstate); zie eslint.config.mjs
    setAdres(dossier.goed?.waarde.adres ?? "");
    setPrijs(dossier.prijs ? String(dossier.prijs.waarde) : "");
    setKadastraal(dossier.goed?.waarde.kadastraleGegevens ?? "");
    setGemeente(dossier.goed?.waarde.gemeente ?? "");
    setAfdeling(dossier.goed?.waarde.afdeling ?? "");
    setHypLast(
      dossier.hypothecaireLasten?.waarde.map((l) => `${l.schuldeiser}: €${l.bedrag}`).join("\n") ?? ""
    );
    setBurgerlijkeStaten(dossier.partijen.waarde.map((p) => p.burgerlijkeStaat ?? ""));
    setGeslachten(dossier.partijen.waarde.map((p) => p.geslacht ?? ""));
    setHuwelijken(
      dossier.partijen.waarde.map((p) => ({
        echtgenoot: p.echtgenoot ?? "",
        plaats: p.huwelijksplaats ?? "",
        datum: p.huwelijksdatum ?? "",
        stelsel: p.huwelijksstelsel ?? "",
      }))
    );
    setStedenbouwOntvangen(dossier.stedenbouwInlichtingenOntvangen?.waarde ?? false);
    setBelastbareWaarde(dossier.belastbareWaarde ? String(dossier.belastbareWaarde.waarde) : "");
    setRelatie(dossier.relatieBelasting?.waarde ?? "rechte_lijn_partner");
    setGoedType(dossier.goedTypeBelasting?.waarde ?? "onroerend");
    setAndereGoederen(dossier.andereGoederenWaarde ? String(dossier.andereGoederenWaarde.waarde) : "");
    setCompromisdatum(dossier.compromisdatum?.waarde ?? "");
    setVerkoopdoc(dossier.verkoopdocument ?? "");
    setVerkoopRegime(dossier.verkoopRegime ?? "gewoon");
    setGebruik(dossier.gebruik ?? "");
    setReferentie(dossier.referentie ?? "");
    setAtt({
      epcDatum: dossier.attesten?.epc?.datum ?? "",
      epcNummer: dossier.attesten?.epc?.nummer ?? "",
      epcLabel: dossier.attesten?.epc?.label ?? "",
      epcGeldig: dossier.attesten?.epc?.geldigTot ?? "",
      bodemDatum: dossier.attesten?.bodem?.datum ?? "",
      bodemInhoud: dossier.attesten?.bodem?.inhoud ?? "",
      keuringOrg: dossier.attesten?.elektrischeKeuring?.organisme ?? "",
      keuringDatum: dossier.attesten?.elektrischeKeuring?.datum ?? "",
      keuringConclusie: dossier.attesten?.elektrischeKeuring?.conclusie ?? "",
      stbDatum: dossier.attesten?.stedenbouw?.datum ?? "",
      stbBestemming: dossier.attesten?.stedenbouw?.bestemming ?? "",
      stbVergunningen: dossier.attesten?.stedenbouw?.vergunningen ?? "",
      asbestDatum: dossier.attesten?.asbest?.datum ?? "",
      asbestNummer: dossier.attesten?.asbest?.nummer ?? "",
      asbestConclusie: dossier.attesten?.asbest?.conclusie ?? "",
      pScore: dossier.attesten?.overstroming?.pScore ?? "",
      gScore: dossier.attesten?.overstroming?.gScore ?? "",
    });
    setVoorschot(dossier.voorschot ? String(dossier.voorschot.waarde) : "");
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dossier?.id, geladen]);

  async function opslaan() {
    if (!dossier) return;
    // Afwijkende waarneming voor het hoofdbedrag uit een ander brondocument:
    // samenvoegen tot één veld zodat de gezaghebbendste bron de effectieve
    // waarde wordt en het verschil als tegenstrijdigheid zichtbaar blijft.
    const altWaarde = Number(altBedrag);
    const heeftAltWaarde = Boolean(altBedrag.trim()) && !Number.isNaN(altWaarde);
    let bijgewerkt: Dossier;
    if (isVerkoopDossier(dossier)) {
      bijgewerkt = {
        ...dossier,
        goed: maakVeld(
          {
            ...dossier.goed?.waarde,
            adres,
            kadastraleGegevens: kadastraal || undefined,
            gemeente: gemeente || undefined,
            afdeling: afdeling || undefined,
          },
          kadastraal ? "kadastraal-uittreksel" : dossier.goed?.bron ?? "manueel"
        ),
        prijs: maakVeld(Number(prijs), dossier.prijs?.bron ?? "manueel"),
        verkoopdocument: verkoopdoc || undefined,
        verkoopRegime: verkoopRegime === "wet-breyne" ? verkoopRegime : undefined,
        gebruik: gebruik || undefined,
        attesten: bouwAttesten(att),
        stedenbouwInlichtingenOntvangen: maakVeld(stedenbouwOntvangen, "stedenbouwkundige-inlichtingen"),
        compromisdatum: compromisdatum
          ? maakVeld(compromisdatum, dossier.compromisdatum?.bron ?? "compromis")
          : undefined,
        voorschot: voorschot
          ? maakVeld(Number(voorschot), dossier.voorschot?.bron ?? "compromis")
          : undefined,
        aangepast: new Date().toISOString(),
      };
      if (hypLast.trim()) {
        bijgewerkt.hypothecaireLasten = maakVeld(
          hypLast
            .split("\n")
            .filter((l) => l.includes(":"))
            .map((l) => {
              const [schuldeiser, bedrag] = l.split(":");
              return {
                schuldeiser: schuldeiser.trim(),
                // Belgische invoerconventie ("180.000", "180.000,50"): via
                // parseBedrag — Number("180.000") zou 180 opleveren.
                bedrag: parseBedrag(bedrag.replace(/[^\d.,]/g, "")) || 0,
                moetGeroyeerdWorden: true,
              };
            }),
          "hypotheekattest"
        );
      }
      if (heeftAltWaarde && bijgewerkt.prijs) {
        bijgewerkt.prijs = maakVeldUitWaarnemingen(
          [
            { waarde: bijgewerkt.prijs.waarde, bron: bijgewerkt.prijs.bron },
            { waarde: altWaarde, bron: altBron },
          ],
          euro
        );
      }
    } else if (heeftOverdrachtsbelastingVelden(dossier)) {
      bijgewerkt = {
        ...dossier,
        belastbareWaarde: maakVeld(Number(belastbareWaarde), dossier.belastbareWaarde?.bron ?? "manueel"),
        relatieBelasting: maakVeld(relatie, "verklaring-partij"),
        goedTypeBelasting: maakVeld(goedType, "verklaring-partij"),
        aangepast: new Date().toISOString(),
      };
      // Overige goederen van de nalatenschap: enkel op een nalatenschapsdossier.
      if (bijgewerkt.dossiertype === "nalatenschap") {
        bijgewerkt.andereGoederenWaarde = andereGoederen
          ? maakVeld(Number(andereGoederen), "verklaring-partij")
          : undefined;
      }
      if (heeftAltWaarde && bijgewerkt.belastbareWaarde) {
        bijgewerkt.belastbareWaarde = maakVeldUitWaarnemingen(
          [
            { waarde: bijgewerkt.belastbareWaarde.waarde, bron: bijgewerkt.belastbareWaarde.bron },
            { waarde: altWaarde, bron: altBron },
          ],
          euro
        );
      }
    } else {
      // Vennootschaps-/testamentdossier: enkel de gedeelde kernvelden.
      bijgewerkt = { ...dossier, aangepast: new Date().toISOString() };
    }
    bijgewerkt.partijen = maakVeld(
      bijgewerkt.partijen.waarde.map((p, i) => ({
        ...p,
        burgerlijkeStaat: burgerlijkeStaten[i] || undefined,
        geslacht: geslachten[i] || undefined,
        echtgenoot: huwelijken[i]?.echtgenoot.trim() || undefined,
        huwelijksplaats: huwelijken[i]?.plaats.trim() || undefined,
        huwelijksdatum: huwelijken[i]?.datum.trim() || undefined,
        huwelijksstelsel: huwelijken[i]?.stelsel.trim() || undefined,
      })),
      bijgewerkt.partijen.bron
    );
    bijgewerkt.referentie = referentie.trim() || undefined;
    bijgewerkt.ontbrekendeStukken = berekenOntbrekendeStukken(bijgewerkt);
    bijgewerkt.tegenstrijdigheden = berekenTegenstrijdigheden(bijgewerkt);
    await slaDossier(bijgewerkt);
    setBewerken(false);
    setAltBedrag("");
  }

  /** Voegt een bijkomend brondocument (intake-JSON van de agent) samen met dit dossier. */
  async function importeerBijkomendBron() {
    if (!dossier) return;
    setImportFout(null);
    setImportMelding(null);
    const json = vindJsonObject(importTekst);
    if (!json) {
      setImportFout("Geen JSON gevonden. Plak het volledige ```json-blok van de agent.");
      return;
    }
    let parsed: unknown;
    try {
      parsed = JSON.parse(json);
    } catch {
      setImportFout("De JSON is ongeldig (kon niet worden ontleed).");
      return;
    }
    const {
      velden,
      attesten,
      referentie: intakeReferentie,
      zonnepanelen,
      syndicusStatus,
      wettelijkVoorkooprecht,
      fiscaalRegime,
      medeEigendomLastenBetwist,
      problemen,
    } = dossierVeldenUitIntake(parsed);
    if (
      Object.keys(velden).length === 0 &&
      !attesten &&
      !intakeReferentie &&
      zonnepanelen === undefined &&
      !syndicusStatus &&
      wettelijkVoorkooprecht === undefined &&
      !fiscaalRegime &&
      medeEigendomLastenBetwist === undefined
    ) {
      setImportFout("Geen bruikbare velden in de JSON (controleer brontype en formaat).");
      return;
    }
    const samengevoegd = voegIntakeVeldenSamen(dossier, velden);
    const samengevoegdeAttesten = voegAttestenSamen(dossier.attesten, attesten);
    if (samengevoegdeAttesten) samengevoegd.attesten = samengevoegdeAttesten;
    if (intakeReferentie && !samengevoegd.referentie) samengevoegd.referentie = intakeReferentie;
    if (fiscaalRegime) samengevoegd.fiscaalRegime = fiscaalRegime;
    if (medeEigendomLastenBetwist !== undefined) samengevoegd.medeEigendomLastenBetwist = medeEigendomLastenBetwist;
    if (zonnepanelen !== undefined) samengevoegd.zonnepanelen = zonnepanelen;
    if (syndicusStatus) samengevoegd.syndicusStatus = syndicusStatus;
    if (wettelijkVoorkooprecht !== undefined) samengevoegd.wettelijkVoorkooprecht = wettelijkVoorkooprecht;
    samengevoegd.aangepast = new Date().toISOString();
    samengevoegd.ontbrekendeStukken = berekenOntbrekendeStukken(samengevoegd);
    const nieuweConflicten = berekenTegenstrijdigheden(samengevoegd);
    samengevoegd.tegenstrijdigheden = nieuweConflicten;
    await slaDossier(samengevoegd);
    setImportTekst("");
    const conflictDeel =
      nieuweConflicten.length > 0
        ? ` ${nieuweConflicten.length} tegenstrijdigheid(en) gemarkeerd ter validatie.`
        : "";
    const probleemDeel = problemen.length > 0 ? ` ${problemen.length} veld(en) overgeslagen.` : "";
    setImportMelding(`Brondocument samengevoegd.${conflictDeel}${probleemDeel}`);
  }

  /**
   * Valideert een tegenstrijdigheid: optioneel wordt een specifieke bron als de
   * juiste aangeduid (die wordt dan de primaire waarde), waarna het conflict als
   * nagekeken wordt gemarkeerd.
   */
  async function valideerTegenstrijdigheid(
    sleutel: NonNullable<Tegenstrijdigheid["veldSleutel"]>,
    bron?: BronType
  ) {
    if (!dossier) return;
    const next: Dossier = { ...dossier };
    if (bron) {
      // Elk veld bestaat enkel op de dossiertypes van zijn veldgroep
      // (discriminated union) — vandaar de narrowing per sleutel.
      switch (sleutel) {
        case "prijs": if (isVerkoopDossier(next) && next.prijs) next.prijs = kiesPrimaireBron(next.prijs, bron); break;
        case "voorschot": if (isVerkoopDossier(next) && next.voorschot) next.voorschot = kiesPrimaireBron(next.voorschot, bron); break;
        case "compromisdatum": if (isVerkoopDossier(next) && next.compromisdatum) next.compromisdatum = kiesPrimaireBron(next.compromisdatum, bron); break;
        case "belastbareWaarde": if (heeftOverdrachtsbelastingVelden(next) && next.belastbareWaarde) next.belastbareWaarde = kiesPrimaireBron(next.belastbareWaarde, bron); break;
        case "goed": if (heeftOnroerendGoedVelden(next) && next.goed) next.goed = kiesPrimaireBron(next.goed, bron); break;
      }
    }
    next.tegenstrijdigheden = berekenTegenstrijdigheden(next).map((t) =>
      t.veldSleutel === sleutel ? { ...t, opgelost: true } : t
    );
    next.aangepast = new Date().toISOString();
    await slaDossier(next);
  }

  async function wijzigStatus(status: DossierStatus) {
    if (!dossier) return;
    const bijgewerkt = { ...dossier, status, aangepast: new Date().toISOString() };
    await slaDossier(bijgewerkt);
  }

  async function schakelChecklistpunt(puntId: string) {
    if (!dossier) return;
    const huidig = dossier.checklistVoortgang ?? {};
    const bijgewerkt: Dossier = {
      ...dossier,
      checklistVoortgang: { ...huidig, [puntId]: !huidig[puntId] },
      aangepast: new Date().toISOString(),
    };
    await slaDossier(bijgewerkt);
  }

  function naarAktekosten() {
    if (!dossier || !dossier.prijs) return;
    schrijfAktekostenHandoff({ akteType: "verkoop", bedrag: String(dossier.prijs.waarde) });
    router.push("/ereloon");
  }

  function naarKredietAktekosten() {
    if (!kredietBedrag || kredietBedrag <= 0) return;
    schrijfAktekostenHandoff({ akteType: "hypotheek", bedrag: String(kredietBedrag) });
    router.push("/ereloon");
  }

  function naarOpzoekingen() {
    if (!opzoekingenHandeling) return;
    router.push(`/vastgoed?gewest=${gewestNaarCode[gewest]}&handeling=${opzoekingenHandeling.id}`);
  }

  function naarOntwerpakte() {
    if (!dossier || !dossier.goed) return;
    schrijfOntwerpakteHandoff({
      akteType: "verkoopakte",
      parameterwaarden: dossierNaarParameterwaarden(dossier),
      partijHerhalingen: dossierNaarPartijHerhalingen(dossier),
      keuzes: dossierNaarKeuzes(dossier, gewest),
      dossierLabel: dossier.goed.waarde.adres,
    });
    router.push("/modeldocumenten");
  }

  function naarCompromis() {
    if (!dossier || !dossier.goed) return;
    schrijfOntwerpakteHandoff({
      akteType: "verkoopovereenkomst (compromis)",
      parameterwaarden: dossierNaarParameterwaarden(dossier),
      partijHerhalingen: dossierNaarPartijHerhalingen(dossier),
      keuzes: dossierNaarKeuzes(dossier, gewest),
      dossierLabel: dossier.goed.waarde.adres,
    });
    router.push("/modeldocumenten");
  }

  function naarSchenkingsakte() {
    if (!dossier || !dossier.belastbareWaarde) return;
    schrijfOntwerpakteHandoff({
      akteType: "schenkingsakte",
      parameterwaarden: dossierNaarParameterwaarden(dossier),
      partijHerhalingen: dossierNaarPartijHerhalingen(dossier),
      dossierLabel: dossierTitel,
    });
    router.push("/modeldocumenten");
  }

  function naarAutonoomOntwerp() {
    if (!dossier || !autonoom?.model || !autonoom.akteTypeKeuze.akteType) return;
    schrijfOntwerpakteHandoff({
      akteType: autonoom.akteTypeKeuze.akteType,
      parameterwaarden: dossierNaarParameterwaarden(dossier),
      partijHerhalingen: dossierNaarPartijHerhalingen(dossier),
      keuzes: dossierNaarKeuzes(dossier, gewest),
      dossierLabel: dossierTitel,
    });
    router.push("/modeldocumenten");
  }

  function naarModelbrief() {
    if (!dossier) return;
    schrijfModelbriefHandoff({
      categorie: modelmails?.categorieen[0] ?? "akteontwerp",
      parameterwaarden: dossierNaarModelbriefWaarden(dossier),
      dossierLabel: dossierTitel,
    });
    router.push("/modelbrieven");
  }

  function naarBelasting() {
    if (!dossier || !dossier.belastbareWaarde) return;
    schrijfBelastingHandoff({
      bedrag: String(dossier.belastbareWaarde.waarde),
      relatie: dossier.relatieBelasting?.waarde ?? "rechte_lijn_partner",
      goedType: dossier.goedTypeBelasting?.waarde ?? "onroerend",
      andereGoederen: dossier.andereGoederenWaarde ? String(dossier.andereGoederenWaarde.waarde) : undefined,
      dossierLabel: dossierTitel,
    });
    router.push("/belasting");
  }

  function naarSchenkingAktekosten() {
    if (!dossier || !dossier.belastbareWaarde) return;
    const roerend = dossier.goedTypeBelasting?.waarde === "roerend";
    const aantalSchenkers = dossier.partijen.waarde.filter((p) => p.rol === "schenker").length;
    schrijfSchenkingHandoff({
      akteType: roerend ? "schenking-roerend" : "schenking-onroerend",
      bedrag: String(dossier.belastbareWaarde.waarde),
      relatie: dossier.relatieBelasting?.waarde ?? "rechte_lijn_partner",
      aantalSchenkers: aantalSchenkers > 0 ? aantalSchenkers : undefined,
    });
    router.push("/ereloon");
  }

  async function verwijderen() {
    if (!dossier) return;
    if (!confirm("Dossier definitief verwijderen?")) return;
    await verwijderDossier(dossier.id);
    router.push("/dossier");
  }

  async function koppelen() {
    if (!dossier || !koppelDoelId) return;
    const doel = dossiers.find((d) => d.id === koppelDoelId);
    if (!doel || !kanKoppelen(dossier, doel).ok) return;
    const { van, naar } = koppelDossiers(dossier, doel, koppelRelatie, new Date().toISOString());
    await slaDossier(van);
    await slaDossier(naar);
    setKoppelDoelId("");
  }

  async function ontkoppelen(doelId: string) {
    if (!dossier) return;
    const nu = new Date().toISOString();
    const doel = dossiers.find((d) => d.id === doelId);
    if (!doel) {
      // Verbroken koppeling (doeldossier verwijderd): enkel deze zijde opschonen.
      await slaDossier(verwijderVerbrokenKoppeling(dossier, doelId, nu));
      return;
    }
    const { van, naar } = ontkoppelDossiers(dossier, doel, nu);
    await slaDossier(van);
    await slaDossier(naar);
  }

  if (!dossier) return <div className="p-6 text-sm text-slate-400">Laden...</div>;

  const dossierTitel = verkoopDossier
    ? dossier.goed?.waarde.adres ?? "—"
    : dossier.partijen.waarde.map((p) => p.naam).join(", ") || "—";

  return (
    <div className="p-6 max-w-3xl mx-auto">
      <div className="flex items-center justify-between mb-4">
        <div>
          <h1 className="text-xl font-semibold">{dossierTitel}</h1>
          <p className="text-xs text-slate-500">{DOSSIERTYPE_LABEL[dossier.dossiertype]}</p>
        </div>
        <div className="flex gap-2">
          <button
            onClick={() => setBewerken((b) => !b)}
            className="text-sm px-3 py-1.5 rounded-md border border-slate-300 hover:bg-slate-50"
          >
            {bewerken ? "Annuleren" : "Bewerken"}
          </button>
          <button
            onClick={verwijderen}
            className="text-sm px-3 py-1.5 rounded-md border border-red-200 text-red-600 hover:bg-red-50"
          >
            Verwijderen
          </button>
        </div>
      </div>

      <div className="mb-4">
        <label className="text-xs text-slate-500 block mb-1">Status</label>
        <select
          value={dossier.status}
          onChange={(e) => wijzigStatus(e.target.value as DossierStatus)}
          className="border border-slate-300 rounded-md px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
        >
          {STATUSSEN.map((s) => (
            <option key={s} value={s}>
              {DOSSIERSTATUS_LABEL[s]}
            </option>
          ))}
        </select>
      </div>

      {werkdossier && autonoom && (
        <div className="bg-violet-50 border border-violet-200 rounded-xl shadow-sm p-4 mb-4">
          <div className="flex items-center justify-between gap-3 flex-wrap">
            <div>
              <p className="text-sm font-medium text-violet-900">Autonoom werkdossier opstellen</p>
              <p className="text-xs text-violet-700 mt-0.5">
                Stelt in één keer de drie onderdelen samen ter nazicht: ontwerpdocument
                (akteType: {autonoom.akteTypeKeuze.akteType || "nog niet bepaald"}),{" "}
                {werkdossier.modelmails.mails.length} modelmail(s) en de afrekening
                {werkdossier.afrekening.aktekosten || werkdossier.afrekening.belasting
                  ? " (berekend)"
                  : " (niet beschikbaar)"}
                .
              </p>
            </div>
            <button
              onClick={naarAutonoomOntwerp}
              disabled={!autonoom.model || !autonoom.akteTypeKeuze.akteType}
              className="text-sm px-4 py-2 rounded-md font-medium bg-violet-600 text-white hover:bg-violet-700 shrink-0 disabled:opacity-40 disabled:cursor-not-allowed"
            >
              Genereer ontwerp →
            </button>
          </div>
          {werkdossier.onzekerheden.length > 0 && (
            <div className="mt-3">
              <p className="text-xs font-medium text-violet-900 mb-1">
                Na te kijken ({werkdossier.onzekerheden.length}):
              </p>
              <ul className="space-y-1 text-xs text-violet-800">
                {werkdossier.onzekerheden.map((o, i) => (
                  <li key={i} className="flex gap-1.5">
                    <span className="uppercase text-[10px] font-semibold text-violet-500 shrink-0 mt-0.5">
                      {o.pijler}
                    </span>
                    <span>
                      {o.boodschap}
                      {o.suggestie && <span className="text-violet-600"> → {o.suggestie}</span>}
                    </span>
                  </li>
                ))}
              </ul>
            </div>
          )}
        </div>
      )}

      {opvolging && opvolging.stappen.length > 0 && (
        <div className="bg-emerald-50 border border-emerald-200 rounded-xl shadow-sm p-4 mb-4">
          <p className="text-sm font-medium text-emerald-900">Opvolging tot de ondertekening</p>
          <div className="flex flex-wrap gap-1.5 mt-2">
            {opvolging.stappen.map((s) => (
              <span
                key={s.status}
                className={`text-[11px] px-2 py-0.5 rounded-full border ${
                  s.toestand === "huidig"
                    ? "bg-emerald-600 text-white border-emerald-600 font-medium"
                    : s.toestand === "afgerond"
                      ? "bg-emerald-100 text-emerald-700 border-emerald-200 line-through"
                      : "bg-white text-emerald-700 border-emerald-200"
                }`}
              >
                {s.toestand === "afgerond" ? "✓ " : ""}
                {s.titel}
              </span>
            ))}
          </div>
          {opvolging.termijnen.length > 0 && (
            <div className="mt-3">
              <p className="text-xs font-medium text-emerald-900 mb-1">Lopende termijnen:</p>
              <ul className="space-y-1 text-xs">
                {opvolging.termijnen.map((t) => (
                  <li
                    key={t.id}
                    className={
                      t.verstreken
                        ? "text-red-700 font-medium"
                        : t.dagenResterend !== undefined && t.dagenResterend <= 14
                          ? "text-amber-700 font-medium"
                          : "text-emerald-800"
                    }
                  >
                    {t.titel}: {t.vervaldatumVoluit}
                    {t.dagenResterend !== undefined && (
                      <> ({t.verstreken ? `${-t.dagenResterend} dag(en) verstreken` : `nog ${t.dagenResterend} dag(en)`})</>
                    )}
                    <span className="text-emerald-600 font-normal"> — {t.grondslag}</span>
                  </li>
                ))}
              </ul>
            </div>
          )}
          {opvolging.huidigeStap && (
            <div className="mt-3">
              <p className="text-xs font-medium text-emerald-900 mb-1">Volgende acties:</p>
              <ul className="list-disc list-inside space-y-0.5 text-xs text-emerald-800">
                {opvolging.huidigeStap.acties.map((a, i) => (
                  <li key={i}>{a}</li>
                ))}
              </ul>
              {opvolging.huidigeStap.mailCategorieen.length > 0 && (
                <p className="text-[11px] text-emerald-600 mt-1.5">
                  Passende modelmail-categorie(ën):{" "}
                  {opvolging.huidigeStap.mailCategorieen.map((c) => briefCategorieLabels[c]).join(", ")}
                </p>
              )}
            </div>
          )}
        </div>
      )}

      {verkoopDossier && (
        <div className="bg-brand-50 border border-brand-200 rounded-xl shadow-sm p-4 mb-4 flex items-center justify-between gap-3 flex-wrap">
          <div>
            <p className="text-sm font-medium text-brand-900">Ontwerp opstellen</p>
            <p className="text-xs text-brand-700 mt-0.5">
              Genereert het compromis (onderhandse verkoopovereenkomst) of de authentieke
              verkoopakte met de uit dit dossier gekende gegevens (partijen, prijs, goed) al
              voorgevuld; de rest blijft als [AAN TE VULLEN] staan ter nazicht.
            </p>
          </div>
          <div className="flex gap-2 shrink-0 flex-wrap">
            <button
              onClick={naarCompromis}
              className="text-sm px-4 py-2 rounded-md font-medium bg-brand-600 text-white hover:bg-brand-700"
            >
              Genereer compromis →
            </button>
            <button
              onClick={naarOntwerpakte}
              className="text-sm px-4 py-2 rounded-md font-medium bg-white border border-brand-300 text-brand-700 hover:bg-brand-100"
            >
              Genereer verkoopakte →
            </button>
          </div>
        </div>
      )}

      {dossier.dossiertype === "schenking" && dossier.belastbareWaarde && (
        <div className="bg-brand-50 border border-brand-200 rounded-xl shadow-sm p-4 mb-4 flex items-center justify-between gap-3 flex-wrap">
          <div>
            <p className="text-sm font-medium text-brand-900">Ontwerpakte opstellen</p>
            <p className="text-xs text-brand-700 mt-0.5">
              Genereert de schenkingsakte met de uit dit dossier gekende gegevens (partijen,
              belastbare waarde) al voorgevuld; de rest blijft als [AAN TE VULLEN] staan ter
              nazicht. Vereist een schenkingsakte-model in de modeldocumentenbibliotheek.
            </p>
          </div>
          <button
            onClick={naarSchenkingsakte}
            className="text-sm px-4 py-2 rounded-md font-medium bg-brand-600 text-white hover:bg-brand-700 shrink-0"
          >
            Genereer ontwerpakte →
          </button>
        </div>
      )}

      <div className="bg-sky-50 border border-sky-200 rounded-xl shadow-sm p-4 mb-4 flex items-center justify-between gap-3 flex-wrap">
        <div>
          <p className="text-sm font-medium text-sky-900">Modelmail opstellen</p>
          <p className="text-xs text-sky-700 mt-0.5">
            {modelmails && modelmails.categorieen.length > 0 ? (
              <>
                Relevante categorie(ën) uit dit dossier:{" "}
                {modelmails.categorieen.map((c) => briefCategorieLabels[c]).join(", ")} (
                {modelmails.mails.length} modelmail(s)). Opent de bibliotheek met de gekende
                gegevens al voorgevuld; kies daar de passende mail en varianten.
              </>
            ) : (
              "Opent de modelbrievenbibliotheek met de gekende partijen, prijs en ontbrekende stukken al voorgevuld; kies daar de passende modelmail en varianten."
            )}
          </p>
        </div>
        <button
          onClick={naarModelbrief}
          className="text-sm px-4 py-2 rounded-md font-medium bg-sky-600 text-white hover:bg-sky-700 shrink-0"
        >
          Open modelbrieven →
        </button>
      </div>

      {opzoekingenHandeling && (
        <div className="bg-emerald-50 border border-emerald-200 rounded-xl shadow-sm p-4 mb-4 flex items-center justify-between gap-3 flex-wrap">
          <div>
            <p className="text-sm font-medium text-emerald-900">Verplichte opzoekingen</p>
            <p className="text-xs text-emerald-700 mt-0.5">
              Opent de opzoekingsmatrix voor &ldquo;{opzoekingenHandeling.naam}&rdquo; in {gewest}:
              welke attesten en opzoekingen verplicht zijn vóór compromis en akte.
            </p>
          </div>
          <button
            onClick={naarOpzoekingen}
            className="text-sm px-4 py-2 rounded-md font-medium bg-emerald-600 text-white hover:bg-emerald-700 shrink-0"
          >
            Open opzoekingen →
          </button>
        </div>
      )}

      {!verkoopDossier && dossier.belastbareWaarde && (
        <div className="bg-amber-50 border border-amber-200 rounded-xl shadow-sm p-4 mb-4 flex items-center justify-between gap-3 flex-wrap">
          <div>
            <p className="text-sm font-medium text-amber-900">Schenk-/erfbelasting berekenen</p>
            <p className="text-xs text-amber-700 mt-0.5">
              Opent de belastingmodule met de belastbare waarde, verwantschap en aard van het
              goed al voorgevuld.
            </p>
          </div>
          <button
            onClick={naarBelasting}
            className="text-sm px-4 py-2 rounded-md font-medium bg-amber-600 text-white hover:bg-amber-700 shrink-0"
          >
            Open belasting →
          </button>
        </div>
      )}

      {dossier.dossiertype === "schenking" && dossier.belastbareWaarde && (
        <div className="bg-violet-50 border border-violet-200 rounded-xl shadow-sm p-4 mb-4 flex items-center justify-between gap-3 flex-wrap">
          <div>
            <p className="text-sm font-medium text-violet-900">Aktekosten berekenen</p>
            <p className="text-xs text-violet-700 mt-0.5">
              Opent de ereloonmodule voor de schenkingsakte met het bedrag, de verwantschap en
              het aantal schenkers al voorgevuld.
            </p>
          </div>
          <button
            onClick={naarSchenkingAktekosten}
            className="text-sm px-4 py-2 rounded-md font-medium bg-violet-600 text-white hover:bg-violet-700 shrink-0"
          >
            Open aktekosten →
          </button>
        </div>
      )}

      {overzicht && (
        <div className="bg-white border border-slate-200 rounded-xl shadow-sm p-4 mb-4">
          <div className="flex items-center justify-between mb-2">
            <p className="text-sm font-medium text-slate-700">
              Indicatieve afrekening ({gewest})
            </p>
            <div className="flex gap-2">
              {kredietBedrag !== undefined && kredietBedrag > 0 && (
                <button
                  onClick={naarKredietAktekosten}
                  className="text-xs px-3 py-1.5 rounded-md border border-brand-300 text-brand-700 hover:bg-brand-50"
                  title="Opent de ereloonmodule voor de kredietakte (hypotheekvestiging) met het kredietbedrag voorgevuld"
                >
                  Kredietakte →
                </button>
              )}
              <button
                onClick={naarAktekosten}
                className="text-xs px-3 py-1.5 rounded-md border border-brand-300 text-brand-700 hover:bg-brand-50"
              >
                Volledige afrekening →
              </button>
            </div>
          </div>
          <dl className="text-sm text-slate-600 grid grid-cols-2 gap-y-1">
            <dt>Ereloon (excl. btw)</dt>
            <dd className="text-right font-mono">{euro(overzicht.honorarium)}</dd>
            <dt>Kosten (excl. btw)</dt>
            <dd className="text-right font-mono">
              {euro(overzicht.aktekost + overzicht.indBedrag + overzicht.levBedrag)}
            </dd>
            <dt>Btw</dt>
            <dd className="text-right font-mono">{euro(overzicht.btw)}</dd>
            <dt className="font-medium text-slate-800">Aktekosten + ereloon</dt>
            <dd className="text-right font-mono font-medium text-slate-800">
              {euro(overzicht.totaal)}
            </dd>
            {registratiebelasting && (
              <>
                <dt className="col-span-2 border-t border-slate-200 mt-1 pt-1" />
                <dt>Registratiebelasting</dt>
                <dd className="text-right font-mono">{euro(registratiebelasting.bedrag)}</dd>
              </>
            )}
            {aktekostenKrediet && (
              <>
                <dt>Kredietakte (kosten + ereloon)</dt>
                <dd className="text-right font-mono">{euro(aktekostenKrediet.totaal)}</dd>
              </>
            )}
            {registratiebelasting && (
              <>
                <dt className="font-semibold text-slate-900">Geraamd totaal</dt>
                <dd className="text-right font-mono font-semibold text-slate-900">
                  {euro(overzicht.totaal + registratiebelasting.bedrag + (aktekostenKrediet?.totaal ?? 0))}
                </dd>
              </>
            )}
          </dl>
          {registratiebelasting && (
            <p className="text-[11px] text-slate-400 mt-2">
              {registratiebelasting.label}
              {registratiebelasting.opmerking ? ` — ${registratiebelasting.opmerking}` : ""}
            </p>
          )}
        </div>
      )}

      {forfaitaireAfrekening && (
        <div className="bg-white border border-slate-200 rounded-xl shadow-sm p-4 mb-4">
          <p className="text-sm font-medium text-slate-700 mb-2">
            Indicatieve afrekening ({gewest})
          </p>
          <dl className="text-sm text-slate-600 grid grid-cols-2 gap-y-1">
            <dt>{forfaitaireAfrekening.aktekost.label}</dt>
            <dd className="text-right font-mono">{euro(forfaitaireAfrekening.aktekost.bedrag)}</dd>
            <dt>Recht op geschriften</dt>
            <dd className="text-right font-mono">{euro(forfaitaireAfrekening.rechtOpGeschriften)}</dd>
            <dt>Btw</dt>
            <dd className="text-right font-mono">{euro(forfaitaireAfrekening.btw)}</dd>
            <dt className="font-medium text-slate-800">Geraamde kosten</dt>
            <dd className="text-right font-mono font-medium text-slate-800">
              {euro(forfaitaireAfrekening.totaal)}
            </dd>
            <dt className="col-span-2 border-t border-slate-200 mt-1 pt-1" />
            <dt className="text-slate-500">Honorarium</dt>
            <dd className="text-right text-slate-500">door de notaris te bepalen</dd>
          </dl>
          <p className="text-[11px] text-slate-400 mt-2">
            {forfaitaireAfrekening.honorariumToelichting}
          </p>
        </div>
      )}

      <div className="bg-indigo-50/50 border border-indigo-200 rounded-xl shadow-sm p-4 mb-4">
        <p className="text-sm font-medium text-indigo-900 mb-1">Bijkomend brondocument importeren</p>
        <p className="text-xs text-slate-500 mb-2">
          Laat je AI-agent een volgend stuk (eigendomstitel, kadastraal uittreksel, attest, …) omzetten naar
          intake-JSON met het juiste &lsquo;bron&rsquo;-type en plak het hier. De waarden worden samengevoegd: de
          gezaghebbendste bron primeert, afwijkingen blijven als tegenstrijdigheid zichtbaar. De gegevens blijven
          lokaal.
        </p>
        <textarea
          className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full font-mono h-24 focus:outline-none focus:ring-2 focus:ring-indigo-400 focus:border-indigo-400"
          placeholder={'Plak hier het ```json-blok van de agent…'}
          value={importTekst}
          onChange={(e) => {
            setImportTekst(e.target.value);
            setImportMelding(null);
            setImportFout(null);
          }}
        />
        <button
          onClick={importeerBijkomendBron}
          disabled={!importTekst.trim()}
          className="text-sm px-4 py-2 rounded-md font-medium bg-indigo-600 text-white hover:bg-indigo-700 mt-2 disabled:opacity-40 disabled:cursor-not-allowed"
        >
          Samenvoegen met dit dossier
        </button>
        {importFout && <p className="text-xs text-rose-700 mt-2">{importFout}</p>}
        {importMelding && <p className="text-xs text-emerald-700 mt-2">{importMelding}</p>}
      </div>

      {dossier.tegenstrijdigheden.length > 0 && (
        <div className="bg-rose-50 border border-rose-200 rounded-xl shadow-sm p-4 mb-4">
          <p className="text-sm font-medium text-rose-800 mb-2">
            Tegenstrijdigheden tussen bronnen
          </p>
          <ul className="space-y-2">
            {dossier.tegenstrijdigheden.map((t) => (
              <li key={t.veld} className="text-sm">
                <span className="font-medium text-rose-900">{t.veld}</span>
                {t.opgelost && (
                  <span className="ml-2 text-xs bg-emerald-100 text-emerald-700 px-2 py-0.5 rounded-md">
                    gevalideerd
                  </span>
                )}
                <ul className="mt-0.5 space-y-1 text-rose-700">
                  {t.waarden.map((w, i) => (
                    <li key={w.bron + i} className="flex items-center gap-2 flex-wrap">
                      <span>
                        {w.waarde} <span className="text-rose-500">({w.bron})</span>
                        {i === 0 && !t.opgelost && (
                          <span className="ml-1 text-xs text-rose-500">— gebruikt (hoogste gezag)</span>
                        )}
                      </span>
                      {t.veldSleutel && !t.opgelost && (
                        <button
                          onClick={() => valideerTegenstrijdigheid(t.veldSleutel!, w.bron)}
                          className="text-[11px] px-2 py-0.5 rounded border border-rose-300 text-rose-700 hover:bg-rose-100"
                        >
                          Gebruik deze
                        </button>
                      )}
                    </li>
                  ))}
                </ul>
                {t.veldSleutel && !t.opgelost && (
                  <button
                    onClick={() => valideerTegenstrijdigheid(t.veldSleutel!)}
                    className="mt-1 text-[11px] px-2 py-0.5 rounded border border-slate-300 text-slate-600 hover:bg-slate-100"
                  >
                    Gezaghebbendste behouden &amp; nagekeken
                  </button>
                )}
              </li>
            ))}
          </ul>
        </div>
      )}

      {dossier.ontbrekendeStukken.length > 0 && (
        <div className="bg-amber-50 border border-amber-200 rounded-xl shadow-sm p-4 mb-4">
          <p className="text-sm font-medium text-amber-800 mb-1">Ontbrekende stukken</p>
          <ul className="text-sm text-amber-700 list-disc list-inside">
            {dossier.ontbrekendeStukken.map((id) => (
              <li key={id}>{stukLabel(id)}</li>
            ))}
          </ul>
        </div>
      )}

      {checklist && (
        <DossierChecklist
          checklist={checklist}
          voortgang={dossier.checklistVoortgang ?? {}}
          onToggle={schakelChecklistpunt}
        />
      )}

      <div className="bg-white border border-slate-200 rounded-xl shadow-sm p-4 mb-4">
        <p className="text-sm font-medium text-slate-700 mb-1">Gekoppelde dossiers</p>
        <p className="text-xs text-slate-500 mb-2">
          Koppel dit dossier aan een ander dossier van het kantoor (kredietdossier, vervolgdossier,
          deeldossier, verwant dossier). De koppeling is vanuit beide dossiers zichtbaar.
        </p>
        {koppelingOverzicht(dossier, dossiers).length > 0 && (
          <ul className="space-y-1.5 mb-3">
            {koppelingOverzicht(dossier, dossiers).map((k) => (
              <li key={k.koppeling.dossierId} className="flex items-center gap-2 text-sm flex-wrap">
                <span className="text-xs text-slate-500">{k.label}</span>
                {k.doel ? (
                  <Link href={`/dossier/${k.doel.id}`} className="text-brand-700 underline hover:text-brand-900">
                    {k.doelLabel}
                  </Link>
                ) : (
                  <span className="text-rose-700">{k.doelLabel}</span>
                )}
                {k.koppeling.toelichting && (
                  <span className="text-xs text-slate-400">— {k.koppeling.toelichting}</span>
                )}
                <button
                  onClick={() => ontkoppelen(k.koppeling.dossierId)}
                  className="text-[11px] px-2 py-0.5 rounded border border-slate-300 text-slate-600 hover:bg-slate-100"
                >
                  Ontkoppel
                </button>
              </li>
            ))}
          </ul>
        )}
        {(() => {
          const koppelbaar = dossiers.filter((d) => kanKoppelen(dossier, d).ok);
          if (koppelbaar.length === 0) {
            return (
              <p className="text-xs text-slate-400">
                Geen (verdere) dossiers beschikbaar om te koppelen.
              </p>
            );
          }
          return (
            <div className="flex items-center gap-2 flex-wrap">
              <span className="text-xs text-slate-500">Dit dossier</span>
              <select
                value={koppelRelatie}
                onChange={(e) => setKoppelRelatie(e.target.value as DossierRelatie)}
                className="border border-slate-300 rounded-md px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
              >
                {DOSSIER_RELATIES.map((r) => (
                  <option key={r} value={r}>
                    {RELATIE_LABEL[r]}
                  </option>
                ))}
              </select>
              <select
                value={koppelDoelId}
                onChange={(e) => setKoppelDoelId(e.target.value)}
                className="border border-slate-300 rounded-md px-2 py-1.5 text-sm min-w-0 max-w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
              >
                <option value="">— kies een dossier —</option>
                {koppelbaar.map((d) => (
                  <option key={d.id} value={d.id}>
                    {dossierKortLabel(d)}
                  </option>
                ))}
              </select>
              <button
                onClick={koppelen}
                disabled={!koppelDoelId}
                className="text-sm px-3 py-1.5 rounded-md font-medium bg-brand-600 text-white hover:bg-brand-700 disabled:opacity-40 disabled:cursor-not-allowed"
              >
                Koppel
              </button>
            </div>
          );
        })()}
      </div>

      {!bewerken ? (
        <div className="space-y-3">
          {verkoopDossier ? (
            <>
              <Veldweergave
                label="Verkoopprijs"
                waarde={`€${(dossier.prijs?.waarde ?? 0).toLocaleString("nl-BE")}`}
                bron={dossier.prijs?.bron ?? "manueel"}
              />
              <Veldweergave label="Adres" waarde={dossier.goed?.waarde.adres ?? "—"} bron={dossier.goed?.bron ?? "manueel"} />
              <Veldweergave
                label="Kadastrale gegevens"
                waarde={dossier.goed?.waarde.kadastraleGegevens ?? "—"}
                bron={dossier.goed?.bron ?? "manueel"}
              />
              {dossier.hypothecaireLasten && (
                <Veldweergave
                  label="Hypothecaire lasten"
                  waarde={dossier.hypothecaireLasten.waarde
                    .map((l) => `${l.schuldeiser}: €${l.bedrag.toLocaleString("nl-BE")}`)
                    .join(", ")}
                  bron={dossier.hypothecaireLasten.bron}
                />
              )}
            </>
          ) : (
            <>
              <Veldweergave
                label="Belastbare waarde"
                waarde={`€${(dossier.belastbareWaarde?.waarde ?? 0).toLocaleString("nl-BE")}`}
                bron={dossier.belastbareWaarde?.bron ?? "manueel"}
              />
              <Veldweergave
                label="Verwantschap"
                waarde={dossier.relatieBelasting ? relatieLabels[dossier.relatieBelasting.waarde] : "—"}
                bron={dossier.relatieBelasting?.bron ?? "manueel"}
              />
              <Veldweergave
                label="Aard van het goed"
                waarde={dossier.goedTypeBelasting?.waarde ?? "—"}
                bron={dossier.goedTypeBelasting?.bron ?? "manueel"}
              />
            </>
          )}
          <Veldweergave
            label="Partijen"
            waarde={dossier.partijen.waarde.map((p) => `${p.naam} (${p.rol})`).join(", ") || "—"}
            bron={dossier.partijen.bron}
          />
        </div>
      ) : (
        <div className="space-y-3">
          <div>
            <label className="text-xs text-slate-500 block mb-1">Kantoorreferentie / dossiernummer</label>
            <input
              className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
              value={referentie}
              onChange={(e) => setReferentie(e.target.value)}
            />
          </div>
          {verkoopDossier ? (
            <>
              <div>
                <label className="text-xs text-slate-500 block mb-1">Op te stellen document</label>
                <div className="flex gap-2">
                  {(["compromis", "verkoopakte"] as const).map((doc) => (
                    <button
                      key={doc}
                      type="button"
                      onClick={() => setVerkoopdoc(doc)}
                      className={`text-sm px-3 py-1.5 rounded-md border ${
                        verkoopdoc === doc
                          ? "border-brand-400 bg-brand-50 text-brand-700"
                          : "border-slate-300 hover:bg-slate-100"
                      }`}
                    >
                      {doc === "compromis" ? "Compromis (onderhands)" : "Verkoopakte (notarieel)"}
                    </button>
                  ))}
                </div>
                <p className="text-[11px] text-slate-400 mt-1">
                  {verkoopdoc === "verkoopakte"
                    ? "Authentieke akte — meestal binnen de vier maanden na de ondertekening van het compromis."
                    : "Onderhandse verkoopovereenkomst — voordien is enkel een bod/aankoopbelofte getekend."}
                </p>
              </div>
              <div>
                <label className="text-xs text-slate-500 block mb-1">Verkoopregime</label>
                <div className="flex gap-2">
                  {(["gewoon", "wet-breyne", "lijfrente"] as const).map((regime) => (
                    <button
                      key={regime}
                      type="button"
                      onClick={() => setVerkoopRegime(regime)}
                      className={`text-sm px-3 py-1.5 rounded-md border ${
                        verkoopRegime === regime
                          ? "border-brand-400 bg-brand-50 text-brand-700"
                          : "border-slate-300 hover:bg-slate-100"
                      }`}
                    >
                      {VERKOOPREGIME_LABEL[regime]}
                    </button>
                  ))}
                </div>
                {VERKOOPREGIME_TOELICHTING[verkoopRegime] && (
                  <p className="text-[11px] text-slate-400 mt-1">{VERKOOPREGIME_TOELICHTING[verkoopRegime]}</p>
                )}
              </div>
              <div>
                <label className="text-xs text-slate-500 block mb-1">Gebruik / genot van het goed</label>
                <select
                  className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                  value={gebruik}
                  onChange={(e) => setGebruik(e.target.value as NonNullable<Dossier["gebruik"]> | "")}
                >
                  <option value="">Onbekend — notaris kiest de hypothese</option>
                  <option value="vrij">Vrij — onmiddellijke inbezitneming</option>
                  <option value="koper-is-huurder">Koper is reeds huurder</option>
                  <option value="verhuurd">Verhuurd overgedragen</option>
                </select>
                <p className="text-[11px] text-slate-400 mt-1">
                  Bepaalt deterministisch de genot-hypothese in het ontwerp.
                </p>
              </div>
              <div>
                <label className="text-xs text-slate-500 block mb-1">Adres</label>
                <input
                  className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                  value={adres}
                  onChange={(e) => setAdres(e.target.value)}
                />
              </div>
              <div>
                <label className="text-xs text-slate-500 block mb-1">Verkoopprijs (€)</label>
                <input
                  type="number"
                  className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                  value={prijs}
                  onChange={(e) => setPrijs(e.target.value)}
                />
              </div>
              <div className="flex gap-3">
                <div className="flex-1">
                  <label className="text-xs text-slate-500 block mb-1">Compromisdatum (uit compromis)</label>
                  <input
                    type="date"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={compromisdatum}
                    onChange={(e) => setCompromisdatum(e.target.value)}
                  />
                </div>
                <div className="flex-1">
                  <label className="text-xs text-slate-500 block mb-1">Voorschot (€, uit compromis)</label>
                  <input
                    type="number"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={voorschot}
                    onChange={(e) => setVoorschot(e.target.value)}
                  />
                </div>
              </div>
              <div>
                <label className="text-xs text-slate-500 block mb-1">
                  Kadastrale gegevens (uit kadastraal uittreksel)
                </label>
                <input
                  className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                  value={kadastraal}
                  onChange={(e) => setKadastraal(e.target.value)}
                />
              </div>
              <div className="flex gap-3">
                <div className="flex-1">
                  <label className="text-xs text-slate-500 block mb-1">Gemeente</label>
                  <input
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={gemeente}
                    onChange={(e) => setGemeente(e.target.value)}
                  />
                </div>
                <div className="flex-1">
                  <label className="text-xs text-slate-500 block mb-1">Afdeling</label>
                  <input
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={afdeling}
                    onChange={(e) => setAfdeling(e.target.value)}
                  />
                </div>
              </div>
              <div>
                <label className="flex items-center gap-2 text-sm text-slate-700">
                  <input
                    type="checkbox"
                    checked={stedenbouwOntvangen}
                    onChange={(e) => setStedenbouwOntvangen(e.target.checked)}
                  />
                  Stedenbouwkundige inlichtingen ontvangen (kost wordt opgenomen in de afrekening)
                </label>
              </div>
              <div className="border-t border-slate-200 pt-3">
                <p className="text-xs font-medium text-slate-600 mb-1">Attesten</p>
                <p className="text-[11px] text-slate-400 mb-2">
                  Vullen het ontwerp automatisch in. Datums als JJJJ-MM-DD. Leeg = blijft [AAN TE VULLEN].
                </p>
                <p className="text-[11px] text-slate-500 mb-1">EPC</p>
                <div className="grid grid-cols-2 gap-2 mb-2">
                  {([
                    ["epcDatum", "Datum (JJJJ-MM-DD)"],
                    ["epcNummer", "Nummer"],
                    ["epcLabel", "Label (bv. C)"],
                    ["epcGeldig", "Geldig tot (JJJJ-MM-DD)"],
                  ] as const).map(([key, ph]) => (
                    <input
                      key={key}
                      placeholder={ph}
                      className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                      value={att[key]}
                      onChange={(e) => setAtt((a) => ({ ...a, [key]: e.target.value }))}
                    />
                  ))}
                </div>
                <p className="text-[11px] text-slate-500 mb-1">Bodemattest (OVAM)</p>
                <div className="grid grid-cols-2 gap-2 mb-2">
                  <input
                    placeholder="Datum (JJJJ-MM-DD)"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.bodemDatum}
                    onChange={(e) => setAtt((a) => ({ ...a, bodemDatum: e.target.value }))}
                  />
                  <input
                    placeholder="Inhoud/besluit"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.bodemInhoud}
                    onChange={(e) => setAtt((a) => ({ ...a, bodemInhoud: e.target.value }))}
                  />
                </div>
                <p className="text-[11px] text-slate-500 mb-1">Keuring elektrische installatie</p>
                <div className="grid grid-cols-3 gap-2">
                  <input
                    placeholder="Keuringsorganisme"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.keuringOrg}
                    onChange={(e) => setAtt((a) => ({ ...a, keuringOrg: e.target.value }))}
                  />
                  <input
                    placeholder="Datum (JJJJ-MM-DD)"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.keuringDatum}
                    onChange={(e) => setAtt((a) => ({ ...a, keuringDatum: e.target.value }))}
                  />
                  <input
                    placeholder="Besluit/conclusie"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.keuringConclusie}
                    onChange={(e) => setAtt((a) => ({ ...a, keuringConclusie: e.target.value }))}
                  />
                </div>
                <p className="text-[11px] text-slate-500 mb-1 mt-2">Stedenbouwkundige inlichtingen</p>
                <div className="grid grid-cols-3 gap-2 mb-2">
                  <input
                    placeholder="Datum (JJJJ-MM-DD)"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.stbDatum}
                    onChange={(e) => setAtt((a) => ({ ...a, stbDatum: e.target.value }))}
                  />
                  <input
                    placeholder="Bestemming (gewestplan/RUP)"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.stbBestemming}
                    onChange={(e) => setAtt((a) => ({ ...a, stbBestemming: e.target.value }))}
                  />
                  <input
                    placeholder="Vergunningstoestand"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.stbVergunningen}
                    onChange={(e) => setAtt((a) => ({ ...a, stbVergunningen: e.target.value }))}
                  />
                </div>
                <p className="text-[11px] text-slate-500 mb-1">Asbestattest (gebouw vóór 2001)</p>
                <div className="grid grid-cols-3 gap-2 mb-2">
                  <input
                    placeholder="Datum (JJJJ-MM-DD)"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.asbestDatum}
                    onChange={(e) => setAtt((a) => ({ ...a, asbestDatum: e.target.value }))}
                  />
                  <input
                    placeholder="Nummer"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.asbestNummer}
                    onChange={(e) => setAtt((a) => ({ ...a, asbestNummer: e.target.value }))}
                  />
                  <input
                    placeholder="Besluit/conclusie"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.asbestConclusie}
                    onChange={(e) => setAtt((a) => ({ ...a, asbestConclusie: e.target.value }))}
                  />
                </div>
                <p className="text-[11px] text-slate-500 mb-1">Overstroming (VIOP-scores)</p>
                <div className="grid grid-cols-2 gap-2">
                  <input
                    placeholder="P-score (perceel)"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.pScore}
                    onChange={(e) => setAtt((a) => ({ ...a, pScore: e.target.value }))}
                  />
                  <input
                    placeholder="G-score (gebouw)"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={att.gScore}
                    onChange={(e) => setAtt((a) => ({ ...a, gScore: e.target.value }))}
                  />
                </div>
              </div>
              <div>
                <label className="text-xs text-slate-500 block mb-1">
                  Hypothecaire lasten (uit hypotheekattest, één per regel: &quot;schuldeiser: bedrag&quot;)
                </label>
                <textarea
                  className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                  rows={3}
                  value={hypLast}
                  onChange={(e) => setHypLast(e.target.value)}
                />
              </div>
            </>
          ) : (
            <>
              <div>
                <label className="text-xs text-slate-500 block mb-1">Belastbare waarde (€)</label>
                <input
                  type="number"
                  className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                  value={belastbareWaarde}
                  onChange={(e) => setBelastbareWaarde(e.target.value)}
                />
              </div>
              <div>
                <label className="text-xs text-slate-500 block mb-1">Verwantschap</label>
                <select
                  className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                  value={relatie}
                  onChange={(e) => setRelatie(e.target.value as Relatie)}
                >
                  {Object.entries(relatieLabels).map(([waarde, label]) => (
                    <option key={waarde} value={waarde}>
                      {label}
                    </option>
                  ))}
                </select>
              </div>
              <div>
                <label className="text-xs text-slate-500 block mb-1">Aard van het goed</label>
                <select
                  className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                  value={goedType}
                  onChange={(e) => setGoedType(e.target.value as GoedeType)}
                >
                  <option value="onroerend">Onroerend goed</option>
                  <option value="roerend">Roerend goed</option>
                  <option value="gezinswoning">Gezinswoning</option>
                </select>
              </div>
              {dossier.dossiertype === "nalatenschap" && (
                <div>
                  <label className="text-xs text-slate-500 block mb-1">
                    Andere goederen van de nalatenschap (€, optioneel)
                  </label>
                  <input
                    type="number"
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm w-full focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={andereGoederen}
                    onChange={(e) => setAndereGoederen(e.target.value)}
                  />
                </div>
              )}
            </>
          )}
          <div className="border-t border-slate-200 pt-3">
            <label className="text-xs text-slate-500 block mb-1">Geslacht en burgerlijke staat per partij</label>
            <p className="text-xs text-slate-400 mb-2">
              Het geslacht bepaalt de aanspreking (&quot;De heer&quot; / &quot;Mevrouw&quot;), de burgerlijke
              staat de identificatiehypothese die automatisch gekozen wordt in de ontwerpakte.
            </p>
            <div className="space-y-2">
              {dossier.partijen.waarde.map((p, i) => (
                <div key={i} className="space-y-2 border-b border-slate-100 pb-2 last:border-0">
                  <div className="flex items-center gap-2">
                  <span className="text-sm text-slate-700 flex-1">
                    {p.naam || `Partij ${i + 1}`} ({p.rol})
                  </span>
                  <select
                    aria-label={`Geslacht ${p.naam || `partij ${i + 1}`}`}
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={geslachten[i] ?? ""}
                    onChange={(e) =>
                      setGeslachten((huidig) => {
                        const nieuw = [...huidig];
                        nieuw[i] = e.target.value as Partij["geslacht"];
                        return nieuw;
                      })
                    }
                  >
                    <option value="">Geslacht?</option>
                    <option value="man">De heer</option>
                    <option value="vrouw">Mevrouw</option>
                  </select>
                  <select
                    aria-label={`Burgerlijke staat ${p.naam || `partij ${i + 1}`}`}
                    className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                    value={burgerlijkeStaten[i] ?? ""}
                    onChange={(e) =>
                      setBurgerlijkeStaten((huidig) => {
                        const nieuw = [...huidig];
                        nieuw[i] = e.target.value as Partij["burgerlijkeStaat"];
                        return nieuw;
                      })
                    }
                  >
                    <option value="">Onbekend — manueel te kiezen</option>
                    <option value="ongehuwd">Ongehuwd</option>
                    <option value="gehuwd">Gehuwd</option>
                    <option value="wettelijk-samenwonend">Wettelijk samenwonend</option>
                    <option value="uit-de-echt-gescheiden">Uit de echt gescheiden / weduwe(naar)</option>
                  </select>
                  </div>
                  {burgerlijkeStaten[i] === "gehuwd" && (
                    <div className="grid grid-cols-2 gap-2 pl-1">
                      {([
                        ["echtgenoot", "Naam echtgeno(o)t(e)"],
                        ["plaats", "Plaats huwelijk"],
                        ["datum", "Datum huwelijk (JJJJ-MM-DD)"],
                        ["stelsel", "Huwelijksstelsel"],
                      ] as const).map(([key, ph]) => (
                        <input
                          key={key}
                          placeholder={ph}
                          className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                          value={huwelijken[i]?.[key] ?? ""}
                          onChange={(e) =>
                            setHuwelijken((huidig) => {
                              const nieuw = [...huidig];
                              const bestaand = nieuw[i] ?? { echtgenoot: "", plaats: "", datum: "", stelsel: "" };
                              nieuw[i] = { ...bestaand, [key]: e.target.value };
                              return nieuw;
                            })
                          }
                        />
                      ))}
                    </div>
                  )}
                </div>
              ))}
            </div>
          </div>
          <div className="border-t border-slate-200 pt-3">
            <label className="text-xs text-slate-500 block mb-1">
              Afwijkend{" "}
              {verkoopDossier ? "verkoopbedrag" : "belastbaar bedrag"} uit een ander stuk (optioneel)
            </label>
            <p className="text-xs text-slate-400 mb-2">
              Vul dit in wanneer een ander brondocument een ander bedrag vermeldt; het stuk met
              het hoogste gezag wordt de gebruikte waarde, het verschil blijft als
              tegenstrijdigheid zichtbaar.
            </p>
            <div className="flex gap-2 flex-wrap">
              <input
                type="number"
                placeholder="Bedrag (€)"
                className="border border-slate-300 rounded-md px-3 py-2 text-sm flex-1 min-w-[8rem] focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                value={altBedrag}
                onChange={(e) => setAltBedrag(e.target.value)}
              />
              <select
                className="border border-slate-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-brand-400 focus:border-brand-400"
                value={altBron}
                onChange={(e) => setAltBron(e.target.value as BronType)}
              >
                {BRON_TYPES.map((b) => (
                  <option key={b} value={b}>
                    {b}
                  </option>
                ))}
              </select>
            </div>
          </div>
          <button
            onClick={opslaan}
            className="bg-brand-600 text-white text-sm px-4 py-2 rounded-md hover:bg-brand-700"
          >
            Opslaan
          </button>
        </div>
      )}
    </div>
  );
}

function Veldweergave({ label, waarde, bron }: { label: string; waarde: string; bron: string }) {
  return (
    <div className="flex items-start justify-between border-b border-slate-100 pb-2">
      <div>
        <p className="text-xs text-slate-500">{label}</p>
        <p className="text-sm">{waarde}</p>
      </div>
      <span className="text-xs bg-slate-100 text-slate-500 px-2 py-0.5 rounded-md">{bron}</span>
    </div>
  );
}
