import { describe, it, expect } from "vitest";
import { vereisteFormaliteiten, voerFormaliteitenUit, FORMALITEITEN_VOLGORDE } from "./formaliteiten-flow";
import { maakMockConnector, DIENST_IMPACT, type ConnectorRegistratie } from "./connector";
import { bepaalZekerheid, type AutonomieRegel } from "@/lib/dossier/autonomie";
import type { Dossier } from "@/lib/dossier/types";
import type { ConnectorDienst } from "./fixtures/types";

// ── AUT-S7 · Formaliteiten-flow ──────────────────────────────────────────────

const dossier = (dossiertype: string): Dossier => ({ id: "d1", dossiertype } as unknown as Dossier);
const zeker = bepaalZekerheid([{ omschrijving: "dossier verleden", positief: true }]);

const verseRegistraties = (): ConnectorRegistratie[] =>
  FORMALITEITEN_VOLGORDE.map((d) => ({ connector: maakMockConnector(d, DIENST_IMPACT[d]), soort: "mock" as const }));

const autonoomRegel = (dienst: ConnectorDienst): AutonomieRegel => ({
  handelingstype: `formaliteit-${dienst}`,
  tier: "handelen-extern",
  impact: "hoog",
  autonoomToegestaan: true,
  minimumNiveau: "zeker",
});

describe("vereisteFormaliteiten", () => {
  it("vereist registratie vóór overschrijving voor een verkoopdossier", () => {
    expect(vereisteFormaliteiten(dossier("verkoop-zonder-krediet"))).toEqual(["registratie", "hypothecaire-overschrijving"]);
  });
  it("vereist geen formaliteiten voor een niet-verkoopdossier", () => {
    expect(vereisteFormaliteiten(dossier("schenking"))).toEqual([]);
  });
});

describe("voerFormaliteitenUit — poort, volgorde, stop-bij-falen", () => {
  it("escaleert bij de default-deny hoge-impact-regel en stopt na de eerste (geen overschrijving zonder registratie)", async () => {
    const r = await voerFormaliteitenUit({
      dossier: dossier("verkoop-zonder-krediet"),
      dossierRef: "dossier-1",
      tijdstip: "2026-06-01T09:00:00.000Z",
      zekerheid: zeker,
      registraties: verseRegistraties(),
    });
    expect(r.perDienst).toHaveLength(1);
    expect(r.perDienst[0]).toMatchObject({ dienst: "registratie", uitkomst: "geescaleerd" });
    expect(r.overgeslagen).toEqual(["hypothecaire-overschrijving"]);
  });

  it("voert beide formaliteiten in volgorde autonoom uit wanneer autonomie aan staat", async () => {
    const r = await voerFormaliteitenUit({
      dossier: dossier("verkoop-zonder-krediet"),
      dossierRef: "dossier-2",
      tijdstip: "2026-06-01T09:00:00.000Z",
      zekerheid: zeker,
      regelVoorDienst: autonoomRegel,
      registraties: verseRegistraties(),
    });
    expect(r.perDienst.map((u) => u.dienst)).toEqual(["registratie", "hypothecaire-overschrijving"]);
    expect(r.perDienst.every((u) => u.uitkomst === "uitgevoerd" && u.antwoord?.status === "ok")).toBe(true);
    expect(r.overgeslagen).toEqual([]);
    expect(r.auditKetting).toHaveLength(2);
  });

  it("stopt de keten bij een niet-aangesloten eerste dienst", async () => {
    // enkel de overschrijving aangesloten, niet de registratie
    const registraties: ConnectorRegistratie[] = [
      { connector: maakMockConnector("hypothecaire-overschrijving", "formaliteit"), soort: "mock" },
    ];
    const r = await voerFormaliteitenUit({
      dossier: dossier("verkoop-zonder-krediet"),
      dossierRef: "dossier-3",
      tijdstip: "2026-06-01T09:00:00.000Z",
      zekerheid: zeker,
      regelVoorDienst: autonoomRegel,
      registraties,
    });
    expect(r.nietAangesloten).toEqual(["registratie"]);
    expect(r.overgeslagen).toEqual(["hypothecaire-overschrijving"]);
    expect(r.perDienst).toEqual([]);
  });
});
