import { describe, it, expect } from "vitest";
import { stelAfrekeningSamenAutonoom } from "./afrekening";
import { maakVeld, type Dossier, type Partij } from "./types";

function maakVerkoop(overschrijf: Partial<Dossier> = {}): Dossier {
  return {
    id: "d1",
    dossiertype: "verkoop-zonder-krediet",
    status: "compromis-ontvangen",
    partijen: maakVeld([{ naam: "Peeters", rol: "koper" } as Partij], "compromis"),
    goed: maakVeld({ adres: "Steenweg 1" }, "kadastraal-uittreksel"),
    prijs: maakVeld(350000, "compromis"),
    ontbrekendeStukken: [],
    tegenstrijdigheden: [],
    aangemaakt: "2026-06-01T00:00:00.000Z",
    aangepast: "2026-06-01T00:00:00.000Z",
    ...overschrijf,
  } as Dossier;
}

describe("stelAfrekeningSamenAutonoom", () => {
  it("berekent de aktekosten én het verkooprecht voor een verkoopdossier met prijs", () => {
    const res = stelAfrekeningSamenAutonoom(maakVerkoop(), "Vlaanderen");
    expect(res.aktekosten).toBeDefined();
    expect(res.belasting).toBeUndefined();
    // Verkooprecht is toegevoegd, afgerond op hele euro's (algemeen tarief 12%).
    expect(res.registratiebelasting).toBeDefined();
    expect(Number.isInteger(res.registratiebelasting?.bedrag)).toBe(true);
    // Het verlaagd tarief voor de enige eigen woning wordt niet blind aangenomen.
    expect(res.onzekerheden.some((o) => /enige eigen woning/i.test(o))).toBe(true);
  });

  it("signaleert een ontbrekende prijs bij een verkoopdossier", () => {
    const res = stelAfrekeningSamenAutonoom(maakVerkoop({ prijs: undefined }), "Vlaanderen");
    expect(res.aktekosten).toBeUndefined();
    expect(res.onzekerheden.some((o) => /verkoopprijs/i.test(o))).toBe(true);
  });

  it("past het verlaagd verkooprecht (enige eigen woning) toe wanneer het dossier dat uitdrukkelijk zegt", () => {
    const res = stelAfrekeningSamenAutonoom(maakVerkoop({ koperEnigeEigenWoning: true }), "Vlaanderen");
    // Vlaanderen, koopsom ≤ €500.000 → 2% i.p.v. 12%.
    expect(res.registratiebelasting?.percentage).toBe(2);
    expect(res.registratiebelasting?.bedrag).toBe(7000); // 2% van 350.000
    // Geen "algemeen tarief"-voorbehoud meer, wél de voorwaarden-controle.
    expect(res.onzekerheden.some((o) => /algemeen tarief: indien de koper/i.test(o))).toBe(false);
    expect(res.onzekerheden.some((o) => /controleer de wettelijke voorwaarden/i.test(o))).toBe(true);
  });

  it("valt terug op het algemeen tarief boven de waardegrens, met motivering", () => {
    const res = stelAfrekeningSamenAutonoom(
      maakVerkoop({ prijs: maakVeld(600000, "compromis"), koperEnigeEigenWoning: true }),
      "Vlaanderen"
    );
    expect(res.registratiebelasting?.percentage).toBe(12);
    expect(res.onzekerheden.some((o) => /waardegrens/i.test(o))).toBe(true);
  });

  it("laat bij een uitdrukkelijk 'geen eigen woning' het voorbehoud weg (algemeen tarief is dan zeker)", () => {
    const res = stelAfrekeningSamenAutonoom(maakVerkoop({ koperEnigeEigenWoning: false }), "Vlaanderen");
    expect(res.registratiebelasting?.percentage).toBe(12);
    expect(res.onzekerheden.some((o) => /enige eigen woning/i.test(o))).toBe(false);
  });

  it("berekent bij een verkoop-met-krediet ook de kosten van de kredietakte zodra het kredietbedrag gekend is", () => {
    const res = stelAfrekeningSamenAutonoom(
      maakVerkoop({
        dossiertype: "verkoop-met-krediet",
        kredietofferte: maakVeld({ bank: "KBC", bedrag: 300000, aanvaard: false }, "kredietofferte"),
      }),
      "Vlaanderen"
    );
    expect(res.aktekostenKrediet).toBeDefined();
    expect(res.aktekostenKrediet!.totaal).toBeGreaterThan(0);
  });

  it("signaleert een verkoop-met-krediet zonder kredietbedrag (kredietakte niet berekenbaar)", () => {
    const res = stelAfrekeningSamenAutonoom(maakVerkoop({ dossiertype: "verkoop-met-krediet" }), "Vlaanderen");
    expect(res.aktekostenKrediet).toBeUndefined();
    expect(res.onzekerheden.some((o) => /kredietakte/i.test(o))).toBe(true);
  });

  it("berekent schenkbelasting én aktekosten bij een volledig schenkingsdossier", () => {
    const dossier = maakVerkoop({
      dossiertype: "schenking",
      prijs: undefined,
      partijen: maakVeld([{ naam: "Janssens", rol: "schenker" } as Partij], "verklaring-partij"),
      belastbareWaarde: maakVeld(200000, "verklaring-partij"),
      goedTypeBelasting: maakVeld("onroerend", "verklaring-partij"),
      relatieBelasting: maakVeld("rechte_lijn_partner", "verklaring-partij"),
    });
    const res = stelAfrekeningSamenAutonoom(dossier, "Vlaanderen");
    expect(res.belasting?.soort).toBe("schenking");
    expect(res.belasting?.resultaat.totaal).toBeGreaterThan(0);
    expect(res.aktekosten).toBeDefined();
    // Geen aparte registratiebelasting bij schenking: dat zou de schenkbelasting
    // dubbel tellen (die zit al in `belasting`).
    expect(res.registratiebelasting).toBeUndefined();
  });

  it("signaleert ontbrekende verwantschap bij een schenking", () => {
    const dossier = maakVerkoop({
      dossiertype: "schenking",
      prijs: undefined,
      belastbareWaarde: maakVeld(200000, "verklaring-partij"),
      goedTypeBelasting: maakVeld("onroerend", "verklaring-partij"),
    });
    const res = stelAfrekeningSamenAutonoom(dossier, "Vlaanderen");
    expect(res.belasting).toBeUndefined();
    expect(res.onzekerheden.some((o) => /verwantschap/i.test(o))).toBe(true);
  });

  it("berekent erfbelasting bij een nalatenschap met verwantschap", () => {
    const dossier = maakVerkoop({
      dossiertype: "nalatenschap",
      prijs: undefined,
      belastbareWaarde: maakVeld(300000, "verklaring-partij"),
      relatieBelasting: maakVeld("rechte_lijn_partner", "verklaring-partij"),
    });
    const res = stelAfrekeningSamenAutonoom(dossier, "Brussel");
    expect(res.belasting?.soort).toBe("erfenis");
    expect(res.onzekerheden.some((o) => /partnerstatus/i.test(o))).toBe(true);
  });

  it("leidt de partnerstatus hard af wanneer testamentRelatie gekend is, zonder onzekerheid", () => {
    const dossier = maakVerkoop({
      dossiertype: "nalatenschap",
      prijs: undefined,
      partijen: maakVeld(
        [{ naam: "Janssens", rol: "erfgenaam", testamentRelatie: "partner" } as Partij],
        "verklaring-partij"
      ),
      belastbareWaarde: maakVeld(300000, "verklaring-partij"),
      relatieBelasting: maakVeld("rechte_lijn_partner", "verklaring-partij"),
    });
    const res = stelAfrekeningSamenAutonoom(dossier, "Brussel");
    expect(res.belasting?.soort).toBe("erfenis");
    expect(res.onzekerheden.some((o) => /partnerstatus/i.test(o))).toBe(false);
  });

  it("geeft een forfaitaire afrekening (geen proportioneel honorarium/belasting) voor een akte van onbepaalde waarde", () => {
    const dossier = maakVerkoop({ dossiertype: "aanpassing-statuten-vennootschap", prijs: undefined });
    const res = stelAfrekeningSamenAutonoom(dossier, "Vlaanderen");
    // Geen waarde-grondslag: geen proportioneel aktekosten-overzicht en geen belasting.
    expect(res.aktekosten).toBeUndefined();
    expect(res.belasting).toBeUndefined();
    // Wél de zekere, gesourcede forfaitaire kosten; het honorarium blijft aan de notaris.
    expect(res.forfaitaireAfrekening).toBeDefined();
    expect(res.forfaitaireAfrekening!.aktekost.bedrag).toBeGreaterThan(0);
    expect(res.forfaitaireAfrekening!.totaal).toBeGreaterThan(0);
    expect(res.onzekerheden.some((o) => /honorarium/i.test(o))).toBe(true);
  });
});
