import { describe, it, expect } from "vitest";
import { kenmerkenNaarKeuzes, heldereTaalKeuzes } from "./kenmerken";

describe("kenmerkenNaarKeuzes", () => {
  it("leidt deterministisch de hypotheses af uit de feiten", () => {
    const keuzes = kenmerkenNaarKeuzes({ gewest: "Vlaanderen", goedType: "appartement", metKrediet: true });
    expect(keuzes).toContainEqual({ onderdeelId: "beschrijving-onroerend-goed", variantId: "appartement-mede-eigendom" });
    expect(keuzes).toContainEqual({ onderdeelId: "risico-verzekering", variantId: "mede-eigendom" });
    expect(keuzes).toContainEqual({ onderdeelId: "administratieve-attesten", variantId: "vlaanderen" });
    expect(keuzes).toContainEqual({ onderdeelId: "opschortende-voorwaarde-financiering", opnemen: true });
  });

  it("kiest standaard vrije inbezitneming, en past het gebruik aan wanneer gegeven", () => {
    expect(kenmerkenNaarKeuzes({})).toContainEqual({ onderdeelId: "eigendomsoverdracht-genot", variantId: "vrij-inbezitneming" });
    expect(kenmerkenNaarKeuzes({ gebruik: "koper-is-huurder" })).toContainEqual({ onderdeelId: "eigendomsoverdracht-genot", variantId: "koper-is-huurder" });
    expect(kenmerkenNaarKeuzes({ gebruik: "verhuurd" })).toContainEqual({ onderdeelId: "verkoop-verhuurd-goed", opnemen: true });
  });

  it("een appartement neemt de mede-eigendom-clausule deterministisch op", () => {
    expect(kenmerkenNaarKeuzes({ goedType: "appartement" })).toContainEqual({ onderdeelId: "mede-eigendom-syndicus", opnemen: true });
    expect(kenmerkenNaarKeuzes({ goedType: "woning" }).some((k) => k.onderdeelId === "mede-eigendom-syndicus")).toBe(false);
  });

  it("neemt verkoop-clausules op op basis van de feiten", () => {
    const keuzes = kenmerkenNaarKeuzes({ zonnepanelen: true, verpacht: true, conventioneelVoorkooprecht: true });
    expect(keuzes).toContainEqual({ onderdeelId: "roerende-goederen-zonnepanelen", opnemen: true });
    expect(keuzes).toContainEqual({ onderdeelId: "verkoop-verpacht-goed", opnemen: true });
    expect(keuzes).toContainEqual({ onderdeelId: "voorkooprechten-conventioneel", opnemen: true });
  });

  it("een 'ander' goed krijgt geen verzekeringsvariant (open te laten)", () => {
    const keuzes = kenmerkenNaarKeuzes({ goedType: "ander" });
    expect(keuzes.some((k) => k.onderdeelId === "risico-verzekering")).toBe(false);
    expect(keuzes).toContainEqual({ onderdeelId: "beschrijving-onroerend-goed", variantId: "ander-goed-zonder-mede-eigendom" });
  });

  it("zonder krediet geen opschortende voorwaarde", () => {
    expect(kenmerkenNaarKeuzes({ metKrediet: false }).some((k) => k.onderdeelId === "opschortende-voorwaarde-financiering")).toBe(false);
  });

  it("schenking met voorbehoud vruchtgebruik neemt de vruchtgebruik-clausule op", () => {
    expect(kenmerkenNaarKeuzes({ voorbehoudVruchtgebruik: true })).toContainEqual({ onderdeelId: "vruchtgebruik-voorbehoud-schenking", opnemen: true });
    expect(kenmerkenNaarKeuzes({}).some((k) => k.onderdeelId === "vruchtgebruik-voorbehoud-schenking")).toBe(false);
  });

  it("neemt de schenking-clausules op op basis van de feiten", () => {
    const keuzes = kenmerkenNaarKeuzes({
      minderjarigeBegiftigde: true,
      schenkingEigenGoedDoorGehuwde: true,
      lastHulpEnBijstand: true,
      meerdereBegiftigden: true,
    });
    expect(keuzes).toContainEqual({ onderdeelId: "aanvaarding-minderjarige-begiftigde-schenking", opnemen: true });
    expect(keuzes).toContainEqual({ onderdeelId: "tussenkomst-echtgenoot-schenking-eigen-goed", opnemen: true });
    expect(keuzes).toContainEqual({ onderdeelId: "last-hulp-en-bijstand-schenking", opnemen: true });
    expect(keuzes).toContainEqual({ onderdeelId: "aanwas-tussen-begiftigden-schenking", opnemen: true });
  });

  it("kiest de juiste variant voor het recht van terugkeer", () => {
    expect(kenmerkenNaarKeuzes({ rechtVanTerugkeer: "conventioneel" })).toContainEqual({ onderdeelId: "recht-van-terugkeer-schenking", variantId: "conventioneel-recht-van-terugkeer" });
    expect(kenmerkenNaarKeuzes({ rechtVanTerugkeer: "wettelijk" })).toContainEqual({ onderdeelId: "recht-van-terugkeer-schenking", variantId: "enkel-wettelijk-recht-van-terugkeer" });
  });

  it("laat een schenking-clausule uitdrukkelijk weg bij een expliciet false-feit (NL én FR)", () => {
    const keuzes = kenmerkenNaarKeuzes({ minderjarigeBegiftigde: false, meerdereBegiftigden: false });
    expect(keuzes).toContainEqual({ onderdeelId: "aanvaarding-minderjarige-begiftigde-schenking", opnemen: false, conditieBevestigd: true });
    expect(keuzes).toContainEqual({ onderdeelId: "aanvaarding-minderjarige-begiftigde-schenking-fr", opnemen: false, conditieBevestigd: true });
    expect(keuzes).toContainEqual({ onderdeelId: "aanwas-tussen-begiftigden-schenking", opnemen: false, conditieBevestigd: true });
  });

  it("stuurt de vertegenwoordigingsclausule aan via partijVertegenwoordigd", () => {
    expect(kenmerkenNaarKeuzes({ partijVertegenwoordigd: false })).toContainEqual({ onderdeelId: "vertegenwoordiging-volmacht", opnemen: false, conditieBevestigd: true });
    expect(kenmerkenNaarKeuzes({ partijVertegenwoordigd: true })).toContainEqual({ onderdeelId: "vertegenwoordiging-volmacht", opnemen: true, conditieBevestigd: true });
    expect(kenmerkenNaarKeuzes({}).some((k) => k.onderdeelId === "vertegenwoordiging-volmacht")).toBe(false);
  });
});

describe("heldereTaalKeuzes — bijkomende deterministische hypotheses (gouden pad)", () => {
  it("kiest de PID-hypothese voor de keuring elektrische installatie (NL + FR)", () => {
    const keuzes = heldereTaalKeuzes({ elektrischeKeuring: "conform" });
    expect(keuzes).toContainEqual({ onderdeelId: "ht-elektrische-keuring", variantId: "keuringsverslag-conform" });
    expect(keuzes).toContainEqual({ onderdeelId: "ht-elektrische-keuring-fr", variantId: "keuringsverslag-conform" });
  });

  it("kiest de syndicus-hypothese van de statuten mede-eigendom (NL + FR)", () => {
    const keuzes = heldereTaalKeuzes({ syndicusInfo: "geen-antwoord" });
    expect(keuzes).toContainEqual({ onderdeelId: "ht-mede-eigendom-statuten", variantId: "syndicus-geen-antwoord" });
    expect(keuzes).toContainEqual({ onderdeelId: "ht-mede-eigendom-statuten-fr", variantId: "syndicus-geen-antwoord" });
  });

  it("kiest de groenestroomcertificaten-hypothese (NL + FR)", () => {
    const keuzes = heldereTaalKeuzes({ groenestroomcertificaten: "met" });
    expect(keuzes).toContainEqual({ onderdeelId: "ht-zonnepanelen", variantId: "met-groenestroomcertificaten" });
    expect(keuzes).toContainEqual({ onderdeelId: "ht-zonnepanelen-fr", variantId: "met-groenestroomcertificaten" });
  });

  it("laat de keuzes open wanneer de feiten ontbreken (veiligheidsprincipe)", () => {
    const keuzes = heldereTaalKeuzes({});
    expect(keuzes.some((k) => k.onderdeelId === "ht-pid-elektrische-keuring")).toBe(false);
    expect(keuzes.some((k) => k.onderdeelId === "ht-reclamepanelen-zonnepanelen")).toBe(false);
  });
});
