import { describe, it, expect } from "vitest";
import {
  controleerAfrekening,
  saldoBlijftPositief,
  magUitbetalen,
  beoordeelDoorstorting,
  type Derdengeldpost,
} from "./derdengelden";

// ── AUT-O7 · Financiële-integriteitsmodel ────────────────────────────────────

const ontvangst = (bedragCent: number, omschrijving = "ontvangst"): Derdengeldpost => ({ omschrijving, richting: "ontvangst", bedragCent });
const uitbetaling = (bedragCent: number, omschrijving = "uitbetaling"): Derdengeldpost => ({ omschrijving, richting: "uitbetaling", bedragCent });

describe("controleerAfrekening", () => {
  it("telt ontvangsten/uitbetalingen op en berekent het saldo", () => {
    const r = controleerAfrekening([ontvangst(40_000_00), uitbetaling(38_000_00), uitbetaling(2_000_00)]);
    expect(r.ontvangstenCent).toBe(40_000_00);
    expect(r.uitbetalingenCent).toBe(40_000_00);
    expect(r.saldoCent).toBe(0);
    expect(r.sluitend).toBe(true);
  });

  it("markeert een niet-sluitende afrekening (saldo ≠ 0)", () => {
    expect(controleerAfrekening([ontvangst(1000), uitbetaling(400)]).sluitend).toBe(false);
  });

  it("markeert een ongeldige post (negatief of niet-geheel bedrag)", () => {
    expect(controleerAfrekening([ontvangst(-5)]).geldig).toBe(false);
    expect(controleerAfrekening([ontvangst(10.5)]).geldig).toBe(false);
  });
});

describe("saldoBlijftPositief — de rekening mag nooit in het rood", () => {
  it("aanvaardt een reeks waarin eerst ontvangen, dan uitbetaald wordt", () => {
    expect(saldoBlijftPositief([ontvangst(1000), uitbetaling(600), uitbetaling(400)])).toEqual({ ok: true });
  });

  it("weigert een reeks waarin op enig moment meer wordt uitbetaald dan ontvangen", () => {
    const r = saldoBlijftPositief([ontvangst(500), uitbetaling(600)]);
    expect(r.ok).toBe(false);
    expect(r.brekingBij).toBe(2);
  });
});

describe("magUitbetalen", () => {
  it("laat een uitbetaling toe tot exact het beschikbare saldo", () => {
    expect(magUitbetalen(1000, 1000)).toBe(true);
    expect(magUitbetalen(1000, 999)).toBe(true);
  });
  it("weigert boven het saldo, nul, negatief of niet-geheel", () => {
    expect(magUitbetalen(1000, 1001)).toBe(false);
    expect(magUitbetalen(1000, 0)).toBe(false);
    expect(magUitbetalen(1000, -5)).toBe(false);
    expect(magUitbetalen(1000, 10.5)).toBe(false);
  });
});

describe("beoordeelDoorstorting", () => {
  const d = { begunstigdeRef: "verkoper", bedragCent: 380_000_00, reden: "netto-verkoopprijs" };

  it("weigert wanneer de doorstorting het dossiersaldo zou overschrijden", () => {
    const r = beoordeelDoorstorting(d, 100_000_00);
    expect(r.beslissing).toBe("geweigerd");
    expect(r.autonoomMogelijk).toBe(false);
  });

  it("bereidt een gedekte doorstorting voor maar escaleert altijd naar de notaris", () => {
    const r = beoordeelDoorstorting(d, 400_000_00);
    expect(r.beslissing).toBe("voorbereid-escaleren");
    expect(r.autonoomMogelijk).toBe(false);
  });

  it("een doorstorting is NOOIT autonoom, ook niet als ze gedekt is", () => {
    expect(beoordeelDoorstorting(d, 400_000_00).autonoomMogelijk).toBe(false);
    expect(beoordeelDoorstorting({ ...d, bedragCent: 1 }, 400_000_00).autonoomMogelijk).toBe(false);
  });

  it("weigert een ongeldig bedrag", () => {
    expect(beoordeelDoorstorting({ ...d, bedragCent: 0 }, 400_000_00).beslissing).toBe("geweigerd");
  });
});
