import { describe, it, expect } from "vitest";
// ── Scenario-testloops voor het compromis gouden pad ─────────────────────────
// Genereert het compromis-ontwerp voor uiteenlopende dossiers en bewaakt dat de
// juiste clausules verschijnen/wegblijven (geen tegenstrijdigheden, juiste
// hypotheses). Vult de A-tot-Z-loop aan met breedte over scenario's.
import { stelOntwerpakteSamenAutonoom } from "./autonoom";
import { dossierNaarParameterwaarden, dossierNaarKeuzes, dossierNaarPartijHerhalingen } from "./parameters";
import { maakVeld, type Dossier } from "./types";
import { seedModellen, seedOnderdelen, genereerDocument, pasKeuzesToe, verwijderOpmaakMarkers } from "@/data/modeldocumenten";

function compromis(extra: Partial<Dossier> = {}): Dossier {
  return {
    id: "d",
    dossiertype: "verkoop-zonder-krediet",
    status: "compromis-ontvangen",
    verkoopdocument: "compromis",
    referentie: "2026/0001",
    partijen: maakVeld(
      [
        { naam: "PEETERS", voornaam: "Jan", rol: "verkoper", geslacht: "man", burgerlijkeStaat: "ongehuwd", adres: "Kerkstraat 8" },
        { naam: "JANSSENS", voornaam: "Anna", rol: "koper", geslacht: "vrouw", burgerlijkeStaat: "ongehuwd", adres: "Veldweg 22" },
      ],
      "compromis"
    ),
    goed: maakVeld({ adres: "Bosstraat 45", type: "woning", gemeente: "Tervuren", sectie: "C", perceelnummer: "88/B", oppervlakte: 540 }, "compromis"),
    prijs: maakVeld(395000, "compromis"),
    voorschot: maakVeld(39500, "compromis"),
    ontbrekendeStukken: [],
    tegenstrijdigheden: [],
    aangemaakt: "2026-06-01T00:00:00.000Z",
    aangepast: "2026-06-01T00:00:00.000Z",
    ...extra,
  } as Dossier;
}

// Deze scenario's toetsen de clausules van het traditionele compromis-model;
// het heldere-taal-compromis (de standaard) wordt elders getest.
const traditioneelModel = seedModellen.find((m) => m.id === "verkoopovereenkomst-compromis")!;
const gen = (d: Dossier) =>
  genereerDocument(
    traditioneelModel,
    seedOnderdelen,
    pasKeuzesToe(traditioneelModel, dossierNaarKeuzes(d, "Vlaanderen")),
    dossierNaarParameterwaarden(d),
    dossierNaarPartijHerhalingen(d)
  );

describe("compromis scenario-testloops", () => {
  it("zonder hypotheek: geen inschrijving-clausule (geen tegenspraak met 'vrij en onbelast')", () => {
    expect(gen(compromis())).not.toContain("bezwaard met een hypothecaire inschrijving");
  });

  it("met te royeren hypotheek: inschrijving-clausule met ingevulde schuldeiser/bedrag", () => {
    const t = gen(compromis({ hypothecaireLasten: maakVeld([{ schuldeiser: "KBC Bank", bedrag: 150000, moetGeroyeerdWorden: true }], "hypotheekattest") }));
    expect(t).toContain("bezwaard met een hypothecaire inschrijving");
    expect(t).toContain("KBC Bank");
    expect(t).not.toContain("[AAN TE VULLEN: naam_schuldeiser]");
  });

  it("appartement: neemt de mede-eigendomclausules op; woning niet", () => {
    expect(gen(compromis({ goed: maakVeld({ adres: "x", type: "appartement", gemeente: "Tervuren" }, "compromis") })).toLowerCase()).toContain("mede-eigendom");
    expect(gen(compromis())).not.toContain("mede-eigendom-syndicus");
  });

  it("gebruik vrij vs verhuurd kiest de juiste genot-hypothese", () => {
    expect(gen(compromis({ gebruik: "vrij" }))).toContain("werkelijke inbezitneming");
    expect(gen(compromis({ gebruik: "verhuurd" }))).toMatch(/verhuur|huurder/i);
  });

  it("met krediet: opschortende voorwaarde van financiering aanwezig", () => {
    expect(gen(compromis({ dossiertype: "verkoop-met-krediet" }))).toMatch(/opschortende voorwaarde|financiering/i);
  });

  it("standaardverkoop: bijzondere hypotheses worden niet stil geschrapt maar als keuze aangeboden", () => {
    const t = gen(compromis());
    // Veiligheid: facultatieve onderdelen blijven staan, uitdrukkelijk gemarkeerd,
    // en hun hypotheses worden ter keuze aangeboden i.p.v. stilzwijgend geschrapt.
    expect(t).toContain("[NAKIJKEN OF SCHRAPPEN: facultatief onderdeel");
    expect(t).toContain("[KIES DE TOEPASSELIJKE HYPOTHESE EN SCHRAP DE OVERIGE:]");
  });

  it("meerdere partijen: ondertekenaars zijn alle partijen", () => {
    const t = gen(compromis({ partijen: maakVeld([
      { naam: "A", voornaam: "X", rol: "verkoper" },
      { naam: "B", voornaam: "Y", rol: "verkoper" },
      { naam: "C", voornaam: "Z", rol: "koper" },
    ], "compromis") }));
    expect(t).toContain("X A, Y B, Z C");
  });

  it("heldere-taal NL+FR: identiteitsblok van de partijen wordt taal-bewust ingevuld", () => {
    const d = compromis({
      partijen: maakVeld([
        { naam: "PEETERS", voornaam: "Jan", rol: "verkoper", burgerlijkeStaat: "ongehuwd", geboorteplaats: "Mechelen", geboortedatum: "1965-02-20", adres: "Kerkstraat 8" },
        { naam: "JANSSENS", voornaam: "Anna", rol: "koper", burgerlijkeStaat: "gehuwd", adres: "Veldweg 22" },
      ], "compromis"),
    });
    // Zoals in productie (autonoom.ts): de waardenset wordt per documenttaal
    // opgebouwd — de canonieke namen dragen dan de juiste taalformattering.
    const render = (id: string) => {
      const model = seedModellen.find((m) => m.id === id)!;
      const taal = (model.taal ?? "nl") as "nl" | "fr";
      const w = dossierNaarParameterwaarden(d, undefined, undefined, taal);
      const h = dossierNaarPartijHerhalingen(d, taal);
      return verwijderOpmaakMarkers(
        genereerDocument(model, seedOnderdelen, pasKeuzesToe(model, dossierNaarKeuzes(d, "Vlaanderen")), w, h)
      );
    };
    const nl = render("verkoopovereenkomst-heldere-taal");
    // Canonieke clausule "identiteit-partijen": NAAM (hoofdletters) + voornamen,
    // geboorte, rijksregisternummer, burgerlijke staat, dan woonplaats.
    expect(nl).toContain("PEETERS Jan, geboren te Mechelen op 20 februari 1965");
    expect(nl).toContain("ongehuwd en geen verklaring van wettelijke samenwoning afgelegd, wonende te Kerkstraat 8");
    expect(nl).not.toContain("[AAN TE VULLEN: identiteit_verkopers]");
    const fr = render("verkoopovereenkomst-heldere-taal-fr");
    expect(fr).toContain("né(e) à Mechelen le 20 février 1965");
    expect(fr).toContain("JANSSENS Anna, né(e) à");
    expect(fr).not.toContain("[AAN TE VULLEN: identite_vendeurs]");
  });

  it("minimaal dossier: genereert zonder fouten een werkdocument", () => {
    const t = gen({ id: "m", dossiertype: "verkoop-zonder-krediet", status: "compromis-ontvangen", verkoopdocument: "compromis", partijen: maakVeld([], "compromis"), ontbrekendeStukken: [], tegenstrijdigheden: [], aangemaakt: "x", aangepast: "x" });
    expect(t).toContain("ONDERHANDSE VERKOOPOVEREENKOMST");
    expect(t.length).toBeGreaterThan(1000);
  });

  // ── Heldere-taal matrix: 2 talen × 3 gewesten × 3 goedtypes ────────────────
  // Bewaakt dat de deterministische hypothese-engine per gewest/goedType de
  // juiste facultatieve heldere-taal-clausules aan/uit zet, in NL én FR.
  const htRender = (modelId: string, d: Dossier, gewest: "Vlaanderen" | "Brussel" | "Wallonië") => {
    const model = seedModellen.find((m) => m.id === modelId)!;
    return verwijderOpmaakMarkers(
      genereerDocument(model, seedOnderdelen, pasKeuzesToe(model, dossierNaarKeuzes(d, gewest)), dossierNaarParameterwaarden(d), dossierNaarPartijHerhalingen(d))
    );
  };
  const metGoed = (type: "woning" | "appartement" | "grond") => compromis({ goed: maakVeld({ adres: "x", type, gemeente: "Tervuren" }, "compromis") });

  it("heldere taal: renovatieplicht enkel in het Vlaams Gewest (NL+FR)", () => {
    expect(htRender("verkoopovereenkomst-heldere-taal", metGoed("woning"), "Vlaanderen")).toContain("DE RENOVATIEPLICHT");
    expect(htRender("verkoopovereenkomst-heldere-taal", metGoed("woning"), "Brussel")).not.toContain("DE RENOVATIEPLICHT");
    expect(htRender("verkoopovereenkomst-heldere-taal", metGoed("woning"), "Wallonië")).not.toContain("DE RENOVATIEPLICHT");
    expect(htRender("verkoopovereenkomst-heldere-taal-fr", metGoed("woning"), "Vlaanderen")).toMatch(/OBLIGATION DE RÉNOVATION|obligation de rénovation/);
    expect(htRender("verkoopovereenkomst-heldere-taal-fr", metGoed("woning"), "Brussel")).not.toMatch(/OBLIGATION DE RÉNOVATION/);
  });

  it("heldere taal: mede-eigendom enkel bij een appartement (NL+FR)", () => {
    expect(htRender("verkoopovereenkomst-heldere-taal", metGoed("appartement"), "Vlaanderen").toLowerCase()).toContain("syndicus");
    expect(htRender("verkoopovereenkomst-heldere-taal", metGoed("woning"), "Vlaanderen").toLowerCase()).not.toContain("statuten van de mede-eigendom");
    expect(htRender("verkoopovereenkomst-heldere-taal-fr", metGoed("appartement"), "Vlaanderen").toLowerCase()).toContain("syndic");
  });

  it("heldere taal FR: beschrijvingsclausule kiest de juiste goedType-hypothese", () => {
    const woning = htRender("verkoopovereenkomst-heldere-taal-fr", metGoed("woning"), "Vlaanderen");
    const grond = htRender("verkoopovereenkomst-heldere-taal-fr", metGoed("grond"), "Vlaanderen");
    expect(woning).toContain("maison sur et avec terrain");
    expect(woning).not.toContain("parcelle [A VERIFIER] de terrain");
    expect(grond).toContain("parcelle [A VERIFIER] de terrain");
    expect(grond).not.toContain("maison sur et avec terrain");
  });

  it("heldere taal: opschortende-voorwaarde-clausule is sluitend (ook zonder krediet)", () => {
    const t = htRender("verkoopovereenkomst-heldere-taal", metGoed("woning"), "Vlaanderen");
    expect(t.toLowerCase()).toMatch(/opschortende voorwaarde/);
  });

  it("standaard (autonoom) compromis = heldere taal", () => {
    const o = stelOntwerpakteSamenAutonoom(compromis(), seedModellen, seedOnderdelen, "Vlaanderen");
    expect(o.akteTypeKeuze.akteType).toBe("verkoopovereenkomst (compromis) - heldere taal");
    expect(o.model?.id).toBe("verkoopovereenkomst-heldere-taal");
  });
});
