import { describe, it, expect } from "vitest";
import {
  bepaalZekerheid,
  grondenUitOnzekerheden,
  beslisEscalatie,
  veiligeStandaardregel,
  type Zekerheidsgrond,
  type AutonomieRegel,
} from "./autonomie";

// ── AUT-O1 · Zekerheids- & escalatiemodel ────────────────────────────────────
// Bewaakt de drie dragende ontwerpbeslissingen: zekerheid afgeleid uit gronden,
// default-deny voor tier 3, en het absolute ambtelijk voorbehoud.

const pos = (omschrijving: string): Zekerheidsgrond => ({ omschrijving, positief: true });
const neg = (omschrijving: string, blokkerend = false): Zekerheidsgrond => ({ omschrijving, positief: false, blokkerend });

describe("bepaalZekerheid — afgeleid, conservatief", () => {
  it("geen gronden → onzeker (geen basis = geen vertrouwen)", () => {
    expect(bepaalZekerheid([]).niveau).toBe("onzeker");
  });

  it("enkel positieve gronden → zeker", () => {
    expect(bepaalZekerheid([pos("alle feiten aanwezig"), pos("gezaghebbende bron")]).niveau).toBe("zeker");
  });

  it("één niet-blokkerende negatieve grond → waarschijnlijk; twee → onzeker", () => {
    expect(bepaalZekerheid([pos("basis ok"), neg("één open detail")]).niveau).toBe("waarschijnlijk");
    expect(bepaalZekerheid([pos("basis ok"), neg("open detail"), neg("nog een")]).niveau).toBe("onzeker");
  });

  it("een blokkerende negatieve grond → altijd onzeker, ongeacht de rest", () => {
    expect(bepaalZekerheid([pos("a"), pos("b"), pos("c"), neg("tegenstrijdige bronnen", true)]).niveau).toBe("onzeker");
  });

  it("draagt de gronden mee als verantwoording", () => {
    const g = [pos("a"), neg("b")];
    expect(bepaalZekerheid(g).gronden).toEqual(g);
  });
});

describe("grondenUitOnzekerheden — sluit aan op de bestaande onzekerhedenlus", () => {
  it("zet elke werkdossier-onzekerheid om in een negatieve grond", () => {
    const gronden = grondenUitOnzekerheden([
      { pijler: "ontwerpakte", boodschap: "akteType niet eenduidig" },
      { pijler: "afrekening", boodschap: "gewest onbekend" },
    ]);
    expect(gronden.every((g) => !g.positief)).toBe(true);
    expect(gronden[0].omschrijving).toContain("ontwerpakte");
    // Een dossier met onzekerheden kan nooit "zeker" scoren op basis da'rvan.
    expect(bepaalZekerheid(gronden).niveau).toBe("onzeker");
  });
});

describe("beslisEscalatie — de vier tiers", () => {
  const zeker = bepaalZekerheid([pos("alles gecontroleerd")]);
  const waarschijnlijk = bepaalZekerheid([pos("basis"), neg("detail")]);

  it("ambtelijk → altijd verboden, ongeacht zekerheid of beleid", () => {
    const regel: AutonomieRegel = { handelingstype: "verlijden", tier: "ambtelijk", impact: "hoog", autonoomToegestaan: true, minimumNiveau: "zeker" };
    expect(beslisEscalatie(regel, zeker).beslissing).toBe("verboden");
  });

  it("tier 1 (genereren) → autonoom", () => {
    const regel: AutonomieRegel = { handelingstype: "ontwerp-opstellen", tier: "genereren", impact: "laag", autonoomToegestaan: false, minimumNiveau: "zeker" };
    expect(beslisEscalatie(regel, waarschijnlijk).beslissing).toBe("autonoom");
  });

  it("tier 2 (bibliotheekmutatie) → escaleren (via voorstel)", () => {
    const regel: AutonomieRegel = { handelingstype: "clausule-toevoegen", tier: "muteren-bibliotheek", impact: "midden", autonoomToegestaan: true, minimumNiveau: "onzeker" };
    expect(beslisEscalatie(regel, zeker).beslissing).toBe("escaleren");
  });

  it("tier 3 default-deny: autonomie niet aangezet → escaleren, zelfs bij volle zekerheid", () => {
    const regel = veiligeStandaardregel("opzoeking-hypothecaire-staat", "midden");
    expect(regel.autonoomToegestaan).toBe(false);
    expect(beslisEscalatie(regel, zeker).beslissing).toBe("escaleren");
  });

  it("tier 3 aangezet maar zekerheid te laag → escaleren", () => {
    const regel: AutonomieRegel = { handelingstype: "mail-versturen", tier: "handelen-extern", impact: "midden", autonoomToegestaan: true, minimumNiveau: "zeker" };
    expect(beslisEscalatie(regel, waarschijnlijk).beslissing).toBe("escaleren");
  });

  it("tier 3 aangezet én zekerheid voldoende → autonoom", () => {
    const regel: AutonomieRegel = { handelingstype: "opzoeking-aanvragen", tier: "handelen-extern", impact: "laag", autonoomToegestaan: true, minimumNiveau: "waarschijnlijk" };
    expect(beslisEscalatie(regel, waarschijnlijk).beslissing).toBe("autonoom");
  });

  it("het besluit draagt altijd een reden en het niveau (audit-trail)", () => {
    const regel = veiligeStandaardregel("doorstorting", "hoog");
    const besluit = beslisEscalatie(regel, zeker);
    expect(besluit.reden.length).toBeGreaterThan(10);
    expect(besluit.zekerheidsniveau).toBe("zeker");
  });
});

describe("veiligeStandaardregel — default-deny + strengste minimum bij hoge impact", () => {
  it("zet autonomie standaard uit", () => {
    expect(veiligeStandaardregel("x", "laag").autonoomToegestaan).toBe(false);
  });
  it("eist 'zeker' voor midden/hoge impact, 'waarschijnlijk' voor lage", () => {
    expect(veiligeStandaardregel("x", "hoog").minimumNiveau).toBe("zeker");
    expect(veiligeStandaardregel("x", "midden").minimumNiveau).toBe("zeker");
    expect(veiligeStandaardregel("x", "laag").minimumNiveau).toBe("waarschijnlijk");
  });
});
