import { describe, it, expect } from "vitest";
import { stelVolledigheidsrapportSamen } from "./volledigheidsrapport";
import { maakVeld, type Dossier } from "./types";
import type { ExtractieResultaat } from "./perceptie";

// ── AUT-S2 · Volledigheids- & tegenstrijdigheidsrapport ───────────────────────

function maakDossier(overschrijf: Partial<Dossier> = {}): Dossier {
  return {
    id: "d1",
    dossiertype: "schenking",
    status: "compromis-ontvangen",
    partijen: maakVeld([{ naam: "Janssens", rol: "schenker" }], "compromis"),
    goed: maakVeld({ adres: "Kerkstraat 1" }, "eigendomstitel"),
    ontbrekendeStukken: [],
    tegenstrijdigheden: [],
    aangemaakt: "2026-01-01T00:00:00.000Z",
    aangepast: "2026-01-01T00:00:00.000Z",
    ...overschrijf,
  } as Dossier;
}

const prijsMetConflict = maakVeld(300000, "compromis");
prijsMetConflict.alternatieven = [{ waarde: 320000, bron: "eigendomstitel" }];

describe("stelVolledigheidsrapportSamen", () => {
  it("meldt een volledig, consistent dossier als 'volledig' met een positieve grond", () => {
    const r = stelVolledigheidsrapportSamen(maakDossier());
    expect(r.status).toBe("volledig");
    expect(r.punten).toEqual([]);
    expect(r.gronden).toEqual([expect.objectContaining({ positief: true })]);
  });

  it("meldt ontbrekende stukken als 'aandachtspunten' (niet kritiek, wel blokkerend)", () => {
    const r = stelVolledigheidsrapportSamen(maakDossier({ dossiertype: "verkoop-zonder-krediet" }));
    expect(r.status).toBe("aandachtspunten");
    expect(r.aantalOpen).toBeGreaterThan(0);
    expect(r.aantalKritiek).toBe(0);
    expect(r.punten.every((p) => p.soort === "ontbrekend-stuk" && p.blokkerend && !p.kritiek)).toBe(true);
    // ontbrekend stuk blokkeert wél autonoom handelen (default-deny, AUT-O1)
    expect(r.gronden.every((g) => g.positief === false && g.blokkerend)).toBe(true);
  });

  it("meldt een onopgeloste tegenstrijdigheid als 'geblokkeerd' (kritiek)", () => {
    const r = stelVolledigheidsrapportSamen(maakDossier({ prijs: prijsMetConflict }));
    expect(r.status).toBe("geblokkeerd");
    const conflict = r.punten.find((p) => p.soort === "tegenstrijdigheid");
    expect(conflict).toMatchObject({ code: "prijs", kritiek: true, blokkerend: true });
    expect(conflict?.omschrijving).toContain("300.000");
  });

  it("respecteert een opgeloste tegenstrijdigheid (verdwijnt uit het rapport)", () => {
    const r = stelVolledigheidsrapportSamen(
      maakDossier({ prijs: prijsMetConflict, tegenstrijdigheden: [{ veld: "Verkoopprijs", waarden: [], opgelost: true }] })
    );
    expect(r.punten.some((p) => p.soort === "tegenstrijdigheid")).toBe(false);
  });

  it("neemt onleesbare bronnen uit de perceptie-extractie op", () => {
    const extractie: ExtractieResultaat = { waarnemingen: [], onbekendeBronnen: ["stuk-x.pdf"] };
    const r = stelVolledigheidsrapportSamen(maakDossier(), extractie);
    expect(r.status).toBe("geblokkeerd");
    expect(r.punten.find((p) => p.soort === "onleesbare-bron")?.omschrijving).toContain("stuk-x.pdf");
  });

  it("houdt de AUT-O1-gronden PII-vrij (geen waarden of bestandsnamen)", () => {
    const extractie: ExtractieResultaat = { waarnemingen: [], onbekendeBronnen: ["geheim-dossier-janssens.pdf"] };
    const r = stelVolledigheidsrapportSamen(maakDossier({ prijs: prijsMetConflict }), extractie);
    const grondentekst = r.gronden.map((g) => g.omschrijving).join(" ");
    expect(grondentekst).not.toContain("300.000");
    expect(grondentekst).not.toContain("320.000");
    expect(grondentekst).not.toContain("janssens");
  });
});
