import { describe, it, expect } from "vitest";
import { vereisteOpzoekingen, voerOpzoekingenUit, OPZOEKINGSDIENSTEN } from "./opzoekingen-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-S4 · Opzoekingen-flow ────────────────────────────────────────────────

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

/** Verse, geïsoleerde mock-adapters (eigen dedupe-state per test). */
const verseRegistraties = (): ConnectorRegistratie[] =>
  OPZOEKINGSDIENSTEN.map((d) => ({ connector: maakMockConnector(d, DIENST_IMPACT[d]), soort: "mock" as const }));

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

describe("vereisteOpzoekingen", () => {
  it("vraagt de volledige opzoekingenset voor een verkoopdossier", () => {
    expect(vereisteOpzoekingen(dossier("verkoop-zonder-krediet"))).toEqual(OPZOEKINGSDIENSTEN);
    expect(OPZOEKINGSDIENSTEN).toContain("hypothecaire-staat");
  });
  it("vraagt geen opzoekingen voor een niet-verkoopdossier", () => {
    expect(vereisteOpzoekingen(dossier("schenking"))).toEqual([]);
  });
});

describe("voerOpzoekingenUit — alles door de AUT-O5-poort", () => {
  it("escaleert elke opzoeking bij de veilige default-deny-regel (connector niet aangeroepen)", async () => {
    const r = await voerOpzoekingenUit({
      dossier: dossier("verkoop-zonder-krediet"),
      dossierRef: "dossier-1",
      tijdstip: "2026-03-01T09:00:00.000Z",
      zekerheid: zeker,
      registraties: verseRegistraties(),
    });
    expect(r.perDienst).toHaveLength(OPZOEKINGSDIENSTEN.length);
    expect(r.perDienst.every((u) => u.uitkomst === "geescaleerd" && u.antwoord === undefined)).toBe(true);
    expect(r.auditKetting).toHaveLength(OPZOEKINGSDIENSTEN.length);
  });

  it("voert autonoom uit tegen de mock wanneer autonomie aan staat en de zekerheid volstaat", async () => {
    const r = await voerOpzoekingenUit({
      dossier: dossier("verkoop-zonder-krediet"),
      dossierRef: "dossier-2",
      tijdstip: "2026-03-01T09:00:00.000Z",
      zekerheid: zeker,
      regelVoorDienst: autonoomRegel,
      registraties: verseRegistraties(),
    });
    expect(r.perDienst.every((u) => u.uitkomst === "uitgevoerd" && u.antwoord?.status === "ok")).toBe(true);
  });

  it("dedupt bij herhaling: dezelfde adapters + dossierRef geven 'herhaald' terug", async () => {
    const registraties = verseRegistraties();
    const opts = {
      dossier: dossier("verkoop-zonder-krediet"),
      dossierRef: "dossier-3",
      tijdstip: "2026-03-01T09:00:00.000Z",
      zekerheid: zeker,
      regelVoorDienst: autonoomRegel,
      registraties,
    };
    await voerOpzoekingenUit(opts);
    const tweede = await voerOpzoekingenUit(opts);
    expect(tweede.perDienst.every((u) => u.antwoord?.status === "ok" && u.antwoord.herhaald === true)).toBe(true);
  });

  it("meldt een niet-aangesloten dienst zonder te raden", async () => {
    const r = await voerOpzoekingenUit({
      dossier: dossier("verkoop-zonder-krediet"),
      dossierRef: "dossier-4",
      tijdstip: "2026-03-01T09:00:00.000Z",
      zekerheid: zeker,
      registraties: [], // geen enkele adapter
    });
    expect(r.perDienst).toEqual([]);
    expect(r.nietAangesloten).toEqual(OPZOEKINGSDIENSTEN);
  });
});
