// ── Nazicht-.docx: échte Word-revisies (w:ins / w:del) — bewaakt ─────────────
// Het hele nut van het conventie-nazicht staat of valt met de revisies: elk
// voorstel moet als aanvaardbare/verwerpbare wijziging in het document staan,
// met Notary.AI als auteur, en 'Wijzigingen bijhouden' moet bij het openen
// actief zijn. Deze test pakt het gegenereerde bestand uit en controleert de
// OOXML rechtstreeks.

import { describe, expect, it } from "vitest";
import JSZip from "jszip";
import { analyseerConventie } from "@/lib/conventie-nazicht/analyse";
import { genereerNazichtWordDocument } from "./genereerNazichtWordDocument";

const EXTERN_COMPROMIS = [
  "ONDERHANDSE VERKOOPOVEREENKOMST",
  "De koper betaalt een voorschot van 10.000 euro rechtstreeks aan de verkoper.",
  "Het goed wordt aanvaard zonder enig verhaal.",
].join("\n");

const DATUM = "2026-07-06T00:00:00Z";

async function genereerEnPakUit() {
  const rapport = analyseerConventie(EXTERN_COMPROMIS, "verkoopovereenkomst (compromis)");
  const buffer = await genereerNazichtWordDocument({
    tekst: EXTERN_COMPROMIS,
    rapport,
    datumIso: DATUM,
  });
  const zip = await JSZip.loadAsync(buffer);
  const documentXml = await zip.file("word/document.xml")!.async("string");
  const settingsXml = await zip.file("word/settings.xml")!.async("string");
  return { documentXml, settingsXml };
}

describe("genereerNazichtWordDocument", () => {
  it("schrijft échte revisies met Notary.AI als auteur en de opgegeven datum", async () => {
    const { documentXml } = await genereerEnPakUit();
    expect(documentXml).toContain("<w:ins ");
    expect(documentXml).toContain("<w:del ");
    expect(documentXml).toContain('w:author="Notary.AI"');
    expect(documentXml).toContain(`w:date="${DATUM}"`);
  });

  it("schrapt de verdachte alinea's als w:delText en behoudt de rest als gewone tekst", async () => {
    const { documentXml } = await genereerEnPakUit();
    // De voorschot-alinea staat als geschrapte tekst in een revisie …
    expect(documentXml).toMatch(/<w:delText[^>]*>[^<]*rechtstreeks aan de verkoper/);
    expect(documentXml).toMatch(/<w:delText[^>]*>[^<]*zonder enig verhaal/);
    // … terwijl de niet-getroffen titelregel gewone tekst blijft.
    expect(documentXml).toMatch(/<w:t[^>]*>[^<]*ONDERHANDSE VERKOOPOVEREENKOMST/);
  });

  it("voegt de vervangtekst en de ontbrekende clausules in als w:ins", async () => {
    const { documentXml } = await genereerEnPakUit();
    // Vervanging van het voorschotbeding: derdenrekening van de notaris.
    expect(documentXml).toContain("derdenrekening van notaris");
    // Ontbrekende essentiële clausule (bodemattest) achteraan ingevoegd.
    expect(documentXml).toContain("bodemattest werd afgeleverd door de OVAM");
    expect(documentXml).toContain("AANVULLENDE CLAUSULES");
  });

  it("arceert de open plekken en motiveringen geel binnen de invoeging", async () => {
    const { documentXml } = await genereerEnPakUit();
    expect(documentXml).toContain('<w:highlight w:val="yellow"/>');
    // Motivering draagt het categorielabel in hoofdletters.
    expect(documentXml).toContain("TE VERMIJDEN — ");
  });

  it("geeft elke revisie een uniek id", async () => {
    const { documentXml } = await genereerEnPakUit();
    const ids = [...documentXml.matchAll(/<w:(?:ins|del) [^>]*w:id="(\d+)"/g)].map((m) => m[1]);
    expect(ids.length).toBeGreaterThan(2);
    expect(new Set(ids).size).toBe(ids.length);
  });

  it("opent met 'Wijzigingen bijhouden' actief (w:trackChanges in settings.xml)", async () => {
    const { settingsXml } = await genereerEnPakUit();
    expect(settingsXml).toContain("<w:trackChanges/>");
    expect(settingsXml).not.toContain("<w:trackRevisions");
  });
});
