import { describe, it, expect } from "vitest";
import { dossierVeldenUitIntake, vindJsonObject, voegIntakeVeldenSamen, voegAttestenSamen, DOSSIER_INTAKE_SCHEMA } from "./intake";
import { berekenTegenstrijdigheden } from "./tegenstrijdigheden";
import { maakVeld, type Dossier } from "./types";
import { aiPrompts } from "@/data/ai-prompts";

function basisIntake(extra: Record<string, unknown> = {}) {
  return {
    schema: DOSSIER_INTAKE_SCHEMA,
    dossiertype: "verkoop-zonder-krediet",
    partijen: [
      { naam: "Janssens", voornaam: "Pieter", rol: "verkoper", geslacht: "man", geboortedatum: "1970-03-12", adres: "Dorpsstraat 1, 3080 Tervuren", burgerlijkeStaat: "gehuwd" },
      { naam: "De Smet", voornaam: "Anna", rol: "koper", geslacht: "vrouw" },
    ],
    goed: { adres: "Lindelaan 12, 3080 Tervuren", type: "woning", gemeente: "Tervuren", kadastraalInkomen: 1450 },
    prijs: 425000,
    voorschot: 42500,
    compromisdatum: "2026-05-12",
    ...extra,
  };
}

describe("dossierVeldenUitIntake", () => {
  it("leest een geldig compromis-intake volledig en zonder problemen in", () => {
    const r = dossierVeldenUitIntake(basisIntake());
    expect(r.problemen).toEqual([]);
    expect(r.dossiertype).toBe("verkoop-zonder-krediet");
    expect(r.velden.partijen?.waarde).toHaveLength(2);
    expect(r.velden.partijen?.bron).toBe("compromis");
    expect(r.velden.partijen?.waarde[0]).toMatchObject({ naam: "Janssens", voornaam: "Pieter", rol: "verkoper", geslacht: "man", burgerlijkeStaat: "gehuwd" });
    expect(r.velden.goed?.waarde).toMatchObject({ adres: "Lindelaan 12, 3080 Tervuren", type: "woning", kadastraalInkomen: 1450 });
    expect(r.velden.prijs?.waarde).toBe(425000);
    expect(r.velden.voorschot?.waarde).toBe(42500);
    expect(r.velden.compromisdatum?.waarde).toBe("2026-05-12");
  });

  it("leest de huwelijksgegevens van een partij in", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        partijen: [
          { naam: "Janssens", voornaam: "Pieter", rol: "verkoper", burgerlijkeStaat: "gehuwd", echtgenoot: "Anna De Smet", huwelijksplaats: "Tervuren", huwelijksdatum: "2010-06-12", huwelijksstelsel: "wettelijk stelsel" },
        ],
      })
    );
    expect(r.velden.partijen?.waarde[0]).toMatchObject({
      echtgenoot: "Anna De Smet",
      huwelijksplaats: "Tervuren",
      huwelijksdatum: "2010-06-12",
      huwelijksstelsel: "wettelijk stelsel",
    });
  });

  it("leest het gebruik/genot in en weigert een ongeldige waarde", () => {
    expect(dossierVeldenUitIntake(basisIntake({ gebruik: "verhuurd" })).gebruik).toBe("verhuurd");
    const fout = dossierVeldenUitIntake(basisIntake({ gebruik: "iets" }));
    expect(fout.gebruik).toBeUndefined();
    expect(fout.problemen.some((p) => /gebruik/.test(p))).toBe(true);
  });

  it("leest de zonnepanelen-vlag (boolean) in en weigert een niet-boolean", () => {
    expect(dossierVeldenUitIntake(basisIntake({ zonnepanelen: false })).zonnepanelen).toBe(false);
    expect(dossierVeldenUitIntake(basisIntake({ zonnepanelen: true })).zonnepanelen).toBe(true);
    expect(dossierVeldenUitIntake(basisIntake({})).zonnepanelen).toBeUndefined();
    const fout = dossierVeldenUitIntake(basisIntake({ zonnepanelen: "ja" }));
    expect(fout.zonnepanelen).toBeUndefined();
    expect(fout.problemen.some((p) => /zonnepanelen/.test(p))).toBe(true);
  });

  it("leest de kantoorreferentie in", () => {
    expect(dossierVeldenUitIntake(basisIntake({ referentie: "2026/0123" })).referentie).toBe("2026/0123");
    expect(dossierVeldenUitIntake(basisIntake({})).referentie).toBeUndefined();
  });

  it("leest het verkoopdocument (compromis/verkoopakte) in en meldt een ongeldige waarde", () => {
    const ok = dossierVeldenUitIntake(basisIntake({ verkoopdocument: "verkoopakte" }));
    expect(ok.verkoopdocument).toBe("verkoopakte");
    const fout = dossierVeldenUitIntake(basisIntake({ verkoopdocument: "iets-anders" }));
    expect(fout.verkoopdocument).toBeUndefined();
    expect(fout.problemen.some((p) => /verkoopdocument/.test(p))).toBe(true);
  });

  it("leest attesten in en negeert lege deelvelden", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        attesten: {
          epc: { datum: "2025-09-01", nummer: "EPC-1", label: "", geldigTot: "2035-09-01" },
          bodem: { datum: "2026-04-15", inhoud: "blanco" },
          elektrischeKeuring: {},
        },
      })
    );
    expect(r.attesten?.epc).toMatchObject({ datum: "2025-09-01", nummer: "EPC-1", geldigTot: "2035-09-01" });
    expect(r.attesten?.epc?.label).toBeUndefined();
    expect(r.attesten?.bodem).toMatchObject({ datum: "2026-04-15", inhoud: "blanco" });
    expect(r.attesten?.elektrischeKeuring).toBeUndefined(); // leeg → weggelaten
  });

  it("voegt attesten samen waarbij nieuwe deelvelden de bestaande overschrijven", () => {
    const a = voegAttestenSamen(
      { epc: { datum: "2025-09-01", label: "C" } },
      { epc: { label: "B" }, bodem: { datum: "2026-04-15" } }
    );
    expect(a?.epc).toMatchObject({ datum: "2025-09-01", label: "B" }); // datum behouden, label vervangen
    expect(a?.bodem).toMatchObject({ datum: "2026-04-15" });
  });

  it("hangt het opgegeven brontype en brondocumentId aan elk veld", () => {
    const r = dossierVeldenUitIntake(basisIntake({ bron: "eigendomstitel", brondocumentId: "titel-2019.pdf" }));
    expect(r.velden.prijs?.bron).toBe("eigendomstitel");
    expect(r.velden.prijs?.brondocumentId).toBe("titel-2019.pdf");
  });

  it("valt terug op brontype 'compromis' bij een onbekend brontype, met een probleem", () => {
    const r = dossierVeldenUitIntake(basisIntake({ bron: "onzin" }));
    expect(r.velden.prijs?.bron).toBe("compromis");
    expect(r.problemen.some((p) => /onbekend brontype/i.test(p))).toBe(true);
  });

  it("slaat ongeldige bedragen en onbekende enums over en meldt ze als probleem", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({ prijs: -5, relatieBelasting: "buurman", partijen: [{ naam: "X", rol: "marsmannetje" }] })
    );
    expect(r.velden.prijs).toBeUndefined();
    expect(r.velden.relatieBelasting).toBeUndefined();
    expect(r.velden.partijen).toBeUndefined();
    expect(r.problemen.some((p) => /prijs/.test(p))).toBe(true);
    expect(r.problemen.some((p) => /relatieBelasting/.test(p))).toBe(true);
    expect(r.problemen.some((p) => /rol/.test(p))).toBe(true);
  });

  it("waarschuwt bij een ontbrekend of fout schema maar leest de velden alsnog in", () => {
    const r = dossierVeldenUitIntake({ dossiertype: "schenking", prijs: 100000 });
    expect(r.problemen.some((p) => /schema/i.test(p))).toBe(true);
    expect(r.dossiertype).toBe("schenking");
    expect(r.velden.prijs?.waarde).toBe(100000);
  });

  it("geeft een duidelijk probleem bij niet-object-invoer", () => {
    expect(dossierVeldenUitIntake("nope").problemen).toHaveLength(1);
    expect(dossierVeldenUitIntake(null).velden).toEqual({});
  });

  it("haalt het JSON-object uit een ```json-codeblok met begeleidende tekst", () => {
    const agentUitvoer = 'Hier is het resultaat:\n\n```json\n{ "schema": "x", "prijs": 100 }\n```\n\nIndicatief — nakijken.';
    const json = vindJsonObject(agentUitvoer);
    expect(json).toBe('{ "schema": "x", "prijs": 100 }');
    expect(JSON.parse(json!)).toEqual({ schema: "x", prijs: 100 });
  });

  it("haalt het JSON-object uit kale tekst tussen { en } en geeft null bij geen object", () => {
    expect(vindJsonObject('rommel { "a": 1 } staart')).toBe('{ "a": 1 }');
    expect(vindJsonObject("geen json hier")).toBeNull();
  });
});

describe("dossierVeldenUitIntake — v2 extraWaarnemingen", () => {
  it("combineert meerdere bronnen per veld tot één veld met alternatieven", () => {
    const r = dossierVeldenUitIntake({
      schema: "notary-ai-dossier-intake/v2",
      dossiertype: "verkoop-zonder-krediet",
      bron: "compromis",
      prijs: 425000,
      extraWaarnemingen: [
        { veld: "prijs", waarde: 430000, bron: "eigendomstitel", brondocumentId: "titel.pdf" },
      ],
    });
    expect(r.problemen).toEqual([]);
    expect(r.velden.prijs?.waarde).toBe(430000);
    expect(r.velden.prijs?.bron).toBe("eigendomstitel");
    expect(r.velden.prijs?.alternatieven?.[0]).toMatchObject({ waarde: 425000, bron: "compromis" });
  });

  it("aanvaardt een extra waarneming als enige waarde wanneer het hoofdveld ontbreekt", () => {
    const r = dossierVeldenUitIntake({
      schema: "notary-ai-dossier-intake/v2",
      dossiertype: "verkoop-zonder-krediet",
      extraWaarnemingen: [{ veld: "voorschot", waarde: 42500, bron: "compromis" }],
    });
    expect(r.velden.voorschot?.waarde).toBe(42500);
    expect(r.velden.voorschot?.alternatieven).toBeUndefined();
  });

  it("meldt een extra waarneming met onbekend brontype, ongeldige waarde of niet-ondersteund veld", () => {
    const r = dossierVeldenUitIntake({
      schema: "notary-ai-dossier-intake/v2",
      dossiertype: "verkoop-zonder-krediet",
      extraWaarnemingen: [
        { veld: "prijs", waarde: 1, bron: "onzin" },
        { veld: "prijs", waarde: -3, bron: "compromis" },
        { veld: "partijen", waarde: [], bron: "compromis" },
      ],
    });
    expect(r.problemen.some((p) => /brontype/i.test(p))).toBe(true);
    expect(r.problemen.some((p) => /positief bedrag/i.test(p))).toBe(true);
    expect(r.problemen.some((p) => /geen extra waarnemingen/i.test(p))).toBe(true);
    expect(r.velden.prijs).toBeUndefined();
  });

  it("aanvaardt v2 zonder schema-waarschuwing", () => {
    const r = dossierVeldenUitIntake({ schema: "notary-ai-dossier-intake/v2", dossiertype: "schenking" });
    expect(r.problemen.some((p) => /schema/i.test(p))).toBe(false);
  });
});

describe("voegIntakeVeldenSamen", () => {
  function bestaandDossier(): Dossier {
    return {
      id: "d1",
      dossiertype: "verkoop-zonder-krediet",
      status: "compromis-ontvangen",
      partijen: maakVeld([{ naam: "Janssens", rol: "verkoper" }], "compromis"),
      goed: maakVeld({ adres: "Lindelaan 12, 3080 Tervuren" }, "compromis"),
      prijs: maakVeld(425000, "compromis"),
      ontbrekendeStukken: [],
      tegenstrijdigheden: [],
      aangemaakt: "2026-06-01T00:00:00.000Z",
      aangepast: "2026-06-01T00:00:00.000Z",
    };
  }

  it("laat de gezaghebbendere bron primeren en bewaart de afwijkende als tegenstrijdigheid", () => {
    const { velden } = dossierVeldenUitIntake({
      schema: DOSSIER_INTAKE_SCHEMA,
      dossiertype: "verkoop-zonder-krediet",
      bron: "eigendomstitel",
      prijs: 430000,
    });
    const samengevoegd = voegIntakeVeldenSamen(bestaandDossier(), velden);
    // Eigendomstitel (gezag 1) > compromis (gezag 3): wordt de primaire waarde.
    expect(samengevoegd.prijs?.waarde).toBe(430000);
    expect(samengevoegd.prijs?.bron).toBe("eigendomstitel");
    expect(samengevoegd.prijs?.alternatieven?.[0]).toMatchObject({ waarde: 425000, bron: "compromis" });
    // De tegenstrijdigheidscontrole pikt het verschil op.
    const conflicten = berekenTegenstrijdigheden(samengevoegd);
    expect(conflicten.some((c) => c.veld === "Verkoopprijs")).toBe(true);
  });

  it("vult ontbrekende velden aan zonder tegenstrijdigheid bij gelijke of nieuwe waarden", () => {
    const { velden } = dossierVeldenUitIntake({
      schema: DOSSIER_INTAKE_SCHEMA,
      dossiertype: "verkoop-zonder-krediet",
      bron: "compromis",
      prijs: 425000,
      voorschot: 42500,
    });
    const samengevoegd = voegIntakeVeldenSamen(bestaandDossier(), velden);
    expect(samengevoegd.voorschot?.waarde).toBe(42500);
    expect(samengevoegd.prijs?.alternatieven).toBeUndefined(); // zelfde prijs → geen conflict
    expect(berekenTegenstrijdigheden(samengevoegd)).toEqual([]);
  });
});

describe("dossierVeldenUitIntake — betaling/krediet/notarissen/titel/mede-eigendom", () => {
  it("leest de nieuwe kern-objecten volledig in", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        betaling: { rekeningKoper: "BE68 5390 0754 7034", naamRekeningKoper: "De Smet Anna", rekeningDerden: "BE12 4300 0000 1234", naamRekeningDerden: "Notariskantoor" },
        kredietofferte: { bank: "KBC", bedrag: 300000, aanvaard: true, termijnWeken: 4 },
        notarissen: { verkoper: "Cédric Dierckx te Tervuren", koper: "Sybille Falla te Brussel" },
        makelaarNaam: "ENGEL & VÖLKERS",
        eigendomstitel: { datum: "2017-08-03", erfdienstbaarheden: "Geen erfdienstbaarheden." },
        medeEigendom: { datumStatuten: "2012-05-25", datumBerichtSyndicus: "2026-05-01", lastenPerTrimester: 450 },
      })
    );
    expect(r.problemen).toEqual([]);
    expect(r.betaling).toMatchObject({ rekeningKoper: "BE68 5390 0754 7034", naamRekeningDerden: "Notariskantoor" });
    expect(r.velden.kredietofferte?.waarde).toMatchObject({ bank: "KBC", bedrag: 300000, aanvaard: true, termijnWeken: 4 });
    expect(r.notarissen).toMatchObject({ verkoper: "Cédric Dierckx te Tervuren", koper: "Sybille Falla te Brussel" });
    expect(r.makelaarNaam).toBe("ENGEL & VÖLKERS");
    expect(r.eigendomstitel).toMatchObject({ datum: "2017-08-03" });
    expect(r.medeEigendom).toMatchObject({ datumStatuten: "2012-05-25", lastenPerTrimester: 450 });
  });

  it("laat makelaarNaam weg wanneer niet aangeleverd (nooit gokken dat er geen makelaar was)", () => {
    const r = dossierVeldenUitIntake(basisIntake({}));
    expect(r.makelaarNaam).toBeUndefined();
  });

  it("slaat een kredietofferte zonder geldig bedrag over met een probleemmelding", () => {
    const r = dossierVeldenUitIntake(basisIntake({ kredietofferte: { bank: "KBC", aanvaard: true } }));
    expect(r.velden.kredietofferte).toBeUndefined();
    expect(r.problemen.some((p) => p.includes("kredietofferte"))).toBe(true);
  });

  it("slaat een niet-object betaling over met een probleemmelding", () => {
    const r = dossierVeldenUitIntake(basisIntake({ betaling: "BE68 5390 0754 7034" }));
    expect(r.betaling).toBeUndefined();
    expect(r.problemen.some((p) => p.includes("betaling"))).toBe(true);
  });

  it("slaat een niet-ISO compromisdatum over met een probleemmelding (rekenbasis termijnbewaking)", () => {
    const r = dossierVeldenUitIntake(basisIntake({ compromisdatum: "12 mei 2026" }));
    expect(r.velden.compromisdatum).toBeUndefined();
    expect(r.problemen.some((p) => p.includes("compromisdatum") && p.includes("JJJJ-MM-DD"))).toBe(true);
  });

  it("leest de vennootschapsgegevens in (vennootschapsdossiers) en vereist minstens de naam", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        dossiertype: "aanpassing-statuten-vennootschap",
        vennootschap: { naam: "Immo Tervuren", zetel: "Stationsstraat 1, 3080 Tervuren", ondernemingsnummer: "0123.456.789", rechtsvorm: "besloten vennootschap" },
      })
    );
    expect(r.problemen).toEqual([]);
    expect(r.velden.vennootschap?.waarde).toEqual({
      naam: "Immo Tervuren",
      zetel: "Stationsstraat 1, 3080 Tervuren",
      ondernemingsnummer: "0123.456.789",
      rechtsvorm: "besloten vennootschap",
    });
    // Zonder naam (of als niet-object): overslaan met een expliciet probleem.
    const zonderNaam = dossierVeldenUitIntake(basisIntake({ vennootschap: { rechtsvorm: "bv" } }));
    expect(zonderNaam.velden.vennootschap).toBeUndefined();
    expect(zonderNaam.problemen.some((p) => p.includes("vennootschap"))).toBe(true);
  });

  it("leest de beschrijvings-/kavelvelden in (goed-uitbreiding, roerende goederen, verdeling, mede-eigendom-kavel)", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        goed: { adres: "Lindelaan 12, 3080 Tervuren", deelgemeente: "Duisburg", afdeling: "6", oppervlakteTitel: "5a 40ca", inleidendeOmschrijving: "Een woonhuis op en met grond" },
        roerendeGoederen: { omschrijving: "de inbouwkeuken", waarde: 5000 },
        verdelingGekochteDelen: "elk voor de onverdeelde helft",
        medeEigendom: { nummerKavel: "appartement 1", aandeelGemeneDelen: "39/100sten", perceelsidentificatie: "0250V2P0002", datumBasisakte: "2012-05-25", notarisBasisakte: "Gaëlle Taton", plaatsNotarisBasisakte: "Luik" },
      })
    );
    expect(r.problemen).toEqual([]);
    expect(r.velden.goed?.waarde).toMatchObject({ deelgemeente: "Duisburg", oppervlakteTitel: "5a 40ca", inleidendeOmschrijving: "Een woonhuis op en met grond" });
    expect(r.roerendeGoederen).toMatchObject({ omschrijving: "de inbouwkeuken", waarde: 5000 });
    expect(r.verdelingGekochteDelen).toBe("elk voor de onverdeelde helft");
    expect(r.medeEigendom).toMatchObject({ nummerKavel: "appartement 1", perceelsidentificatie: "0250V2P0002", notarisBasisakte: "Gaëlle Taton" });
  });

  it("leest sectieTitel/perceelnummerTitel apart in wanneer titel en recent kadastraal uittreksel een ander formaat gebruiken", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        goed: {
          adres: "Avenue des Cormorans 32, 1150 Woluwe-Saint-Pierre",
          sectie: "B",
          perceelnummer: "0060F22P0000",
          sectieTitel: "B",
          perceelnummerTitel: "60 F 22",
        },
      })
    );
    expect(r.problemen).toEqual([]);
    expect(r.velden.goed?.waarde).toMatchObject({
      sectie: "B",
      perceelnummer: "0060F22P0000",
      sectieTitel: "B",
      perceelnummerTitel: "60 F 22",
    });
  });

  it("leest goed.bouwjaar in (asbestinventarisattest, Vlaanderen)", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        goed: { adres: "Lindelaan 12, 3080 Tervuren", bouwjaar: 2015 },
      })
    );
    expect(r.problemen).toEqual([]);
    expect(r.velden.goed?.waarde).toMatchObject({ bouwjaar: 2015 });
  });

  it("leest de huwelijkscontract-gegevens van een partij in", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        partijen: [
          { naam: "Janssens", rol: "verkoper", burgerlijkeStaat: "gehuwd", huwelijkscontractNotaris: "Paul Maselis", huwelijkscontractPlaats: "Leuven", huwelijkscontractDatum: "2010-05-15" },
        ],
      })
    );
    expect(r.velden.partijen?.waarde[0]).toMatchObject({
      huwelijkscontractNotaris: "Paul Maselis",
      huwelijkscontractPlaats: "Leuven",
      huwelijkscontractDatum: "2010-05-15",
    });
  });

  it("leest de wijziging van het huwelijksstelsel van een partij in (bv. uit een CRH-opzoeking)", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        partijen: [
          {
            naam: "Dierckx", rol: "verkoper", burgerlijkeStaat: "gehuwd",
            huwelijkscontractNotaris: "Christine Van Haeren", huwelijkscontractPlaats: "Turnhout", huwelijkscontractDatum: "1988-06-22",
            notarisWijzigingStelsel: "Fabienne Genicot", plaatsWijzigingStelsel: "Tervuren", datumWijzigingStelsel: "2023-04-17",
            omschrijvingWijzigingStelsel: "zonder het stelsel zelf te wijzigen",
          },
        ],
      })
    );
    expect(r.velden.partijen?.waarde[0]).toMatchObject({
      huwelijkscontractNotaris: "Christine Van Haeren",
      notarisWijzigingStelsel: "Fabienne Genicot",
      plaatsWijzigingStelsel: "Tervuren",
      datumWijzigingStelsel: "2023-04-17",
      omschrijvingWijzigingStelsel: "zonder het stelsel zelf te wijzigen",
    });
  });

  it("leest meerdere opeenvolgende wijzigingen van het huwelijksstelsel in (wijzigingenStelsel)", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        partijen: [
          {
            naam: "Peeters", rol: "verkoper", burgerlijkeStaat: "gehuwd",
            wijzigingenStelsel: [
              { notaris: "Filip Segers", plaats: "Weelde", datum: "2011-03-31", omschrijving: "met behoud van het stelsel" },
              { notaris: "Wim Vanberghen", plaats: "Oud-Turnhout", datum: "2021-06-03", omschrijving: "met toevoeging van een intern gemeenschappelijk vermogen, zonder wijziging van het hoofdstelsel" },
            ],
          },
        ],
      })
    );
    expect(r.velden.partijen?.waarde[0].wijzigingenStelsel).toEqual([
      { notaris: "Filip Segers", plaats: "Weelde", datum: "2011-03-31", omschrijving: "met behoud van het stelsel" },
      { notaris: "Wim Vanberghen", plaats: "Oud-Turnhout", datum: "2021-06-03", omschrijving: "met toevoeging van een intern gemeenschappelijk vermogen, zonder wijziging van het hoofdstelsel" },
    ]);
  });

  it("slaat een onvolledig item in wijzigingenStelsel over (nooit gokken) en meldt het probleem", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        partijen: [
          {
            naam: "Peeters", rol: "verkoper", burgerlijkeStaat: "gehuwd",
            wijzigingenStelsel: [{ plaats: "Weelde", datum: "2011-03-31" }],
          },
        ],
      })
    );
    expect(r.velden.partijen?.waarde[0].wijzigingenStelsel).toBeUndefined();
    expect(r.problemen.some((p) => p.includes("wijzigingenStelsel[0]"))).toBe(true);
  });

  it("leest koperEnigeEigenWoning en hypothecaireLasten in (met verplichte moetGeroyeerdWorden)", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        koperEnigeEigenWoning: true,
        hypothecaireLasten: [
          { schuldeiser: "KBC Bank", bedrag: 180000, moetGeroyeerdWorden: true },
          { schuldeiser: "Zonder vlag", bedrag: 50000 }, // ontbrekende moetGeroyeerdWorden → overslaan
        ],
      })
    );
    expect(r.koperEnigeEigenWoning).toBe(true);
    expect(r.velden.hypothecaireLasten?.waarde).toEqual([
      { schuldeiser: "KBC Bank", bedrag: 180000, moetGeroyeerdWorden: true },
    ]);
    expect(r.problemen.some((p) => p.includes("moetGeroyeerdWorden"))).toBe(true);
  });

  it("leest de nieuwe attest-deelvelden (overstroming datum/conclusie, epc energiedeskundige, bodem refertenummer)", () => {
    const r = dossierVeldenUitIntake(
      basisIntake({
        attesten: {
          epc: { datum: "2026-01-15", nummer: "EPC-987", energiedeskundige: "Ir. J. Peeters" },
          bodem: { datum: "2026-05-02", inhoud: "blanco", refertenummer: "OVAM-1" },
          overstroming: { pScore: "A", gScore: "A", datum: "2026-04-12", conclusie: "geen risico" },
        },
      })
    );
    expect(r.attesten?.epc?.energiedeskundige).toBe("Ir. J. Peeters");
    expect(r.attesten?.bodem?.refertenummer).toBe("OVAM-1");
    expect(r.attesten?.overstroming).toMatchObject({ datum: "2026-04-12", conclusie: "geen risico" });
  });
});

describe("intake-prompt drift", () => {
  it("de intake-prompt gebruikt exact dezelfde schemastring als het contract", () => {
    // data/ mag niet uit lib/ importeren, dus de schemastring staat letterlijk in
    // de prompt — deze test bewaakt dat ze niet uit elkaar lopen.
    const prompt = aiPrompts.find((p) => p.id === "notarieel-dossier-assistent-intake-json");
    expect(prompt).toBeDefined();
    expect(prompt!.prompt).toContain(`"schema": "${DOSSIER_INTAKE_SCHEMA}"`);
    expect(prompt!.doel).toContain(DOSSIER_INTAKE_SCHEMA);
  });

  it("de intake-prompt documenteert de nieuwe kern-objecten van het contract", () => {
    const prompt = aiPrompts.find((p) => p.id === "notarieel-dossier-assistent-intake-json")!;
    for (const sleutel of ['"betaling"', '"kredietofferte"', '"notarissen"', '"eigendomstitel"', '"medeEigendom"', '"roerendeGoederen"', '"verdelingGekochteDelen"', '"koperEnigeEigenWoning"', '"hypothecaireLasten"']) {
      expect(prompt.prompt, `prompt documenteert ${sleutel}`).toContain(sleutel);
    }
  });

  it("de intake-prompt documenteert makelaarNaam", () => {
    const prompt = aiPrompts.find((p) => p.id === "notarieel-dossier-assistent-intake-json")!;
    expect(prompt.prompt).toContain("makelaarNaam");
  });

  it("de intake-prompt documenteert sectieTitel/perceelnummerTitel", () => {
    const prompt = aiPrompts.find((p) => p.id === "notarieel-dossier-assistent-intake-json")!;
    expect(prompt.prompt).toContain("sectieTitel");
    expect(prompt.prompt).toContain("perceelnummerTitel");
  });

  it("de intake-prompt documenteert goed.bouwjaar (asbestinventarisattest, Vlaanderen)", () => {
    const prompt = aiPrompts.find((p) => p.id === "notarieel-dossier-assistent-intake-json")!;
    expect(prompt.prompt).toContain("bouwjaar");
    expect(prompt.prompt).toMatch(/asbestinventarisattest niet vereist/);
  });

  it("de intake-prompt documenteert de wijziging-van-huwelijksstelsel-velden per partij", () => {
    const prompt = aiPrompts.find((p) => p.id === "notarieel-dossier-assistent-intake-json")!;
    for (const sleutel of ["wijzigingenStelsel", "notarisWijzigingStelsel", "plaatsWijzigingStelsel", "datumWijzigingStelsel", "omschrijvingWijzigingStelsel"]) {
      expect(prompt.prompt, `prompt documenteert ${sleutel}`).toContain(sleutel);
    }
  });
});
