import { describe, it, expect } from "vitest";
import { berekenSchenking, berekenErfenis } from "@/data/belastingen";

describe("berekenSchenking — onroerend (geharmoniseerd barema, identiek per gewest)", () => {
  it("rechte lijn/partner: 0 EUR geeft 0 belasting", () => {
    const r = berekenSchenking("Vlaanderen", "onroerend", "rechte_lijn_partner", 0);
    expect(r.totaal).toBe(0);
    expect(r.detail).toEqual([]);
  });

  it("rechte lijn/partner: exact op de eerste schijfgrens (150.000) → enkel 3% schijf", () => {
    // 150.000 * 3% = 4.500
    const r = berekenSchenking("Brussel", "onroerend", "rechte_lijn_partner", 150_000);
    expect(r.totaal).toBe(4500);
    expect(r.detail).toHaveLength(1);
    expect(r.detail[0]).toMatchObject({ van: 0, tot: 150_000, tarief: 3 });
  });

  it("rechte lijn/partner: 200.000 EUR over twee schijven (3% en 9%)", () => {
    // 150.000*3% + 50.000*9% = 4.500 + 4.500 = 9.000
    const r = berekenSchenking("Wallonië", "onroerend", "rechte_lijn_partner", 200_000);
    expect(r.totaal).toBe(9000);
    expect(r.effectiefTarief).toBeCloseTo((9000 / 200_000) * 100, 6);
  });

  it("anderen: 500.000 EUR — zeer hoog bedrag over alle vier schijven (10/20/30/40%)", () => {
    // 150.000*10% + 100.000*20% + 200.000*30% + 50.000*40%
    // = 15.000 + 20.000 + 60.000 + 20.000 = 115.000
    const r = berekenSchenking("Vlaanderen", "onroerend", "anderen", 500_000);
    expect(r.totaal).toBe(115_000);
  });

  it("rechte lijn vs. anderen: zelfde bedrag, verschillende belasting (relatiecategorie)", () => {
    const rechteLijn = berekenSchenking("Vlaanderen", "onroerend", "rechte_lijn_partner", 100_000);
    const anderen = berekenSchenking("Vlaanderen", "onroerend", "anderen", 100_000);
    // 100.000*3% = 3.000 vs. 100.000*10% = 10.000
    expect(rechteLijn.totaal).toBe(3000);
    expect(anderen.totaal).toBe(10_000);
  });

  it("barema is identiek in de drie gewesten voor onroerend", () => {
    const vl = berekenSchenking("Vlaanderen", "onroerend", "broers_zussen", 300_000);
    const br = berekenSchenking("Brussel", "onroerend", "broers_zussen", 300_000);
    const wa = berekenSchenking("Wallonië", "onroerend", "broers_zussen", 300_000);
    expect(vl.totaal).toBe(br.totaal);
    expect(br.totaal).toBe(wa.totaal);
    // 150.000*10% + 100.000*20% + 50.000*30% = 15.000+20.000+15.000 = 50.000
    expect(vl.totaal).toBe(50_000);
  });
});

describe("berekenSchenking — roerend (vast tarief per gewest/relatie)", () => {
  it("Vlaanderen rechte lijn/partner: vast tarief 3%", () => {
    const r = berekenSchenking("Vlaanderen", "roerend", "rechte_lijn_partner", 100_000);
    expect(r.totaal).toBe(3000);
    expect(r.effectiefTarief).toBe(3);
    expect(r.marginaal).toBe(false);
  });

  it("Vlaanderen anderen: vast tarief 7%", () => {
    const r = berekenSchenking("Vlaanderen", "roerend", "anderen", 100_000);
    expect(r.totaal).toBe(7000);
  });

  it("Wallonië rechte lijn/partner: afwijkend vast tarief 3,3% (verschil tussen gewesten)", () => {
    const r = berekenSchenking("Wallonië", "roerend", "rechte_lijn_partner", 100_000);
    expect(r.totaal).toBe(3300);
    expect(r.effectiefTarief).toBe(3.3);
  });

  it("Wallonië broers_zussen/ooms_nichten/anderen: vast tarief 5,5%", () => {
    const r = berekenSchenking("Wallonië", "roerend", "anderen", 50_000);
    expect(r.totaal).toBe(2750);
  });

  it("0 EUR geeft 0 belasting", () => {
    const r = berekenSchenking("Brussel", "roerend", "rechte_lijn_partner", 0);
    expect(r.totaal).toBe(0);
  });

  it("negatief bedrag geeft 0 belasting (randgeval)", () => {
    const r = berekenSchenking("Vlaanderen", "roerend", "anderen", -100);
    expect(r.totaal).toBe(0);
  });
});

describe("berekenErfenis — Vlaanderen", () => {
  it("rechte lijn/partner, onroerend, 100.000 EUR over twee schijven (3% en 9%)", () => {
    // 50.000*3% + 50.000*9% = 1.500 + 4.500 = 6.000
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 100_000, 0, "onroerend", true);
    expect(r.totaal).toBe(6000);
  });

  it("exact op de eerste schijfgrens (50.000) → enkel 3% schijf", () => {
    // 50.000 * 3% = 1.500
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 50_000, 0, "onroerend", true);
    expect(r.totaal).toBe(1500);
  });

  it("zeer hoog bedrag (1.000.000) over alle drie schijven (3/9/27%)", () => {
    // 50.000*3% + 200.000*9% + 750.000*27% = 1.500 + 18.000 + 202.500 = 222.000
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 1_000_000, 0, "onroerend", true);
    expect(r.totaal).toBe(222_000);
  });

  it("gezinswoning is volledig vrijgesteld voor de partner", () => {
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 400_000, 0, "gezinswoning", true);
    expect(r.totaal).toBe(0);
  });

  it("gezinswoning kent in Vlaanderen géén gunsttarief voor afstammelingen (geen partner)", () => {
    // Geen specifieke regeling voor kind/afstammeling in VL → normaal onroerend-barema.
    // 50.000*3% + 50.000*9% = 6.000 (zelfde als gewoon onroerend bij 100.000)
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 100_000, 0, "gezinswoning", false);
    expect(r.totaal).toBe(6000);
  });

  it("roerend goed: eerste 75.000 vrijgesteld voor de partner", () => {
    // Belastbaar: 100.000 - 75.000 = 25.000 → 25.000*3% = 750
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 100_000, 0, "roerend", true);
    expect(r.totaal).toBe(750);
  });

  it("roerend goed onder de vrijstellingsgrens (75.000) voor partner geeft 0", () => {
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 50_000, 0, "roerend", true);
    expect(r.totaal).toBe(0);
  });

  it("bescheiden erfdeel: vermindering bij erfdeel <= 50.000 (geen andere goederen)", () => {
    // basis: 30.000*3% = 900; vermindering = max(0, 500 - 30.000/100) = 500 - 300 = 200
    // gecorrigeerd = 900 - 200 = 700
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 30_000, 0, "onroerend", true);
    expect(r.totaal).toBe(700);
  });

  it("broers en zussen: eigen barema (25/30/55%)", () => {
    // 35.000*25% + 40.000*30% + 25.000*55% (totaal 100.000)
    // = 8.750 + 12.000 + 13.750 = 34.500
    const r = berekenErfenis("Vlaanderen", "broers_zussen", 100_000, 0, "onroerend", false);
    expect(r.totaal).toBe(34_500);
  });

  it("0 EUR geeft 0 belasting", () => {
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 0);
    expect(r.totaal).toBe(0);
  });
});

describe("berekenErfenis — Brussel (abattement 15.000 rechte lijn)", () => {
  it("rechte lijn, 100.000 EUR met abattement van 15.000", () => {
    // Belastbaar: 100.000 - 15.000 = 85.000
    // Schijven BR rechte lijn: 50.000*3% + 35.000*8% = 1.500 + 2.800 = 4.300
    const r = berekenErfenis("Brussel", "rechte_lijn_partner", 100_000, 0, "onroerend", false);
    expect(r.totaal).toBe(4300);
  });

  it("rechte lijn MET andere goederen: abattement vermindert enkel het eigen erfdeel (geen dubbele toepassing)", () => {
    // Eigen erfdeel 100.000 + andere goederen 100.000, abattement 15.000.
    // Correct: belasting op het eigen erfdeel = het marginale deel boven de
    // andere goederen, met het abattement éénmaal van het eigen erfdeel af →
    // belasting(185.000) − belasting(100.000) = 8.550.
    // (Voorheen trok de code het abattement van zowel totaal als basis af,
    //  waardoor het per saldo geen effect had en er 9.750 uitkwam.)
    const r = berekenErfenis("Brussel", "rechte_lijn_partner", 100_000, 100_000, "onroerend", false);
    expect(r.totaal).toBe(8550);
  });

  it("gezinswoning volledig vrijgesteld voor echtgenoot/partner", () => {
    const r = berekenErfenis("Brussel", "rechte_lijn_partner", 600_000, 0, "gezinswoning", true);
    expect(r.totaal).toBe(0);
  });

  it("gezinswoning gunsttarief voor afstammelingen (2/2/5,3%) met abattement 15.000", () => {
    // Belastbaar: 100.000 - 15.000 = 85.000
    // Gunsttarief schijven: 25.000*2% + 25.000*2% + 35.000*5,3% = 500+500+1.855 = 2.855
    const r = berekenErfenis("Brussel", "rechte_lijn_partner", 100_000, 0, "gezinswoning", false);
    expect(r.totaal).toBe(2855);
  });
});

describe("berekenErfenis — Wallonië (abattement conditioneel op erfdeel <= 125.000)", () => {
  it("rechte lijn, erfdeel <= 125.000 → dubbel abattement (25.000)", () => {
    // Belastbaar: 100.000 - 25.000 = 75.000
    // Schijven WA rechte lijn: 12.500*3% + 12.500*4% + 25.000*5% + 25.000*7%
    // = 375 + 500 + 1.250 + 1.750 = 3.875
    const r = berekenErfenis("Wallonië", "rechte_lijn_partner", 100_000, 0, "onroerend", false);
    expect(r.totaal).toBe(3875);
  });

  it("rechte lijn, erfdeel > 125.000 → enkelvoudig abattement (12.500)", () => {
    // Belastbaar: 200.000 - 12.500 = 187.500
    // Schijven: 12.500*3% + 12.500*4% + 25.000*5% + 50.000*7% + 50.000*10% + 37.500*14%
    // = 375 + 500 + 1.250 + 3.500 + 5.000 + 5.250 = 15.875
    const r = berekenErfenis("Wallonië", "rechte_lijn_partner", 200_000, 0, "onroerend", false);
    expect(r.totaal).toBe(15_875);
  });

  it("gezinswoning: abattement van 160.000 voor de langstlevende partner", () => {
    // Belastbaar: 200.000 - 160.000 = 40.000 → 12.500*3% + 12.500*4% + 15.000*5%
    // = 375 + 500 + 750 = 1.625
    const r = berekenErfenis("Wallonië", "rechte_lijn_partner", 200_000, 0, "gezinswoning", true);
    expect(r.totaal).toBe(1625);
  });

  it("broers en zussen: 50.000 EUR over drie schijven (20/25/35%)", () => {
    // 12.500*20% + 12.500*25% + 25.000*35% = 2.500 + 3.125 + 8.750 = 14.375
    const r = berekenErfenis("Wallonië", "broers_zussen", 50_000, 0, "onroerend", false);
    expect(r.totaal).toBe(14_375);
  });
});

describe("berekenErfenis — marginale berekening met andere goederen (progressiviteit)", () => {
  it("een tweede goed wordt belast op het marginale (hogere) tarief, niet vanaf 0", () => {
    // Vlaanderen rechte lijn, eerste goed 250.000 (basis), tweede goed 50.000.
    // Totaal 300.000: schijven 0-50k(3%) 50-250k(9%) 250-300k(27%) =
    //   1.500 + 18.000 + 13.500 = 33.000
    // Basis alleen (250.000): 1.500 + 18.000 = 19.500
    // Marginaal voor het tweede goed: 33.000 - 19.500 = 13.500 (volledig op 27%-schijf)
    const r = berekenErfenis("Vlaanderen", "rechte_lijn_partner", 50_000, 250_000, "onroerend", false);
    expect(r.totaal).toBe(13_500);
    expect(r.marginaal).toBe(true);
  });
});
