// ── AUT-S4 · Opzoekingen-flow (laag 3), mock-eerst ───────────────────────────
// De dossier-gedreven orchestratie van de externe opzoekingen: welke
// opzoekingen dit dossier nodig heeft, en die één voor één door de
// AUT-O5-tier-3-poort (`voerUitMetPoort`) sturen — tegen de geregistreerde
// adapters (vandaag de mocks uit AUT-F4; een echte overheids-API-adapter neemt
// naadloos over via het register). Zo werkt de hele keten intake→opzoekingen al
// end-to-end vóór er ook maar één echte API is aangesloten.
//
// ── Ontwerpbeslissingen ─────────────────────────────────────────────────────
// 1. ALLES DOOR DE POORT. Geen enkele opzoeking wordt rechtstreeks aangeroepen;
//    elke gaat door `voerUitMetPoort`, die de escalatie (AUT-O1) beslist en de
//    audit-ketting (AUT-O2) bijhoudt. Default-deny: zonder uitdrukkelijk
//    aangezette autonomie wordt elke opzoeking geëscaleerd, niet uitgevoerd.
// 2. IDEMPOTENT PER DOSSIER. De idempotentiesleutel is `${dossierRef}/${dienst}`;
//    een dossier tweemaal verwerken herhaalt de opzoeking niet (de mock/echte
//    adapter dedupt).
// 3. DIENST NIET AANGESLOTEN → ZICHTBAAR, NOOIT GERADEN. Ontbreekt de adapter
//    voor een vereiste dienst, dan komt ze in `nietAangesloten` (escaleerbaar),
//    net als een onleesbare bron in de perceptielaag.

import type { Dossier } from "@/lib/dossier/types";
import type { AutonomieRegel, Zekerheid } from "@/lib/dossier/autonomie";
import { veiligeStandaardregel } from "@/lib/dossier/autonomie";
import type { AuditRegel } from "@/lib/dossier/audit";
import type { ConnectorDienst } from "./fixtures/types";
import type { ConnectorAntwoord, ConnectorRegistratie } from "./connector";
import { ALLE_DIENSTEN, DIENST_IMPACT } from "./connector";
import { voerUitMetPoort } from "./connector";
import { connectorVoorDienst } from "./register";

/** Alle diensten met impact "opzoeking" (read-only; de formaliteiten zijn AUT-S7). */
export const OPZOEKINGSDIENSTEN: ConnectorDienst[] = ALLE_DIENSTEN.filter((d) => DIENST_IMPACT[d] === "opzoeking");

/**
 * De opzoekingen die een dossier nodig heeft. Vandaag: een verkoopdossier
 * vereist de volledige set vastgoedopzoekingen; andere dossiertypes hebben (nog)
 * geen gemodelleerde opzoekingenset. Puur.
 */
export function vereisteOpzoekingen(dossier: Dossier): ConnectorDienst[] {
  if (dossier.dossiertype === "verkoop-met-krediet" || dossier.dossiertype === "verkoop-zonder-krediet") {
    return [...OPZOEKINGSDIENSTEN];
  }
  return [];
}

/** De uitkomst van één opzoeking in de flow. */
export interface OpzoekingUitkomst {
  dienst: ConnectorDienst;
  uitkomst: "uitgevoerd" | "geescaleerd" | "verboden";
  antwoord?: ConnectorAntwoord;
  reden: string;
}

/** De uitkomst van de hele opzoekingen-flow voor een dossier. */
export interface OpzoekingenResultaat {
  perDienst: OpzoekingUitkomst[];
  /** Vereiste diensten zonder geregistreerde adapter — nooit geraden. */
  nietAangesloten: ConnectorDienst[];
  /** De audit-ketting mét alle toegevoegde regels (AUT-O2). */
  auditKetting: AuditRegel[];
}

/**
 * Voert de vereiste opzoekingen van een dossier uit via de AUT-O5-poort. Puur op
 * de invoer na de connectoren zelf (die zijn deterministisch bij de mocks).
 * `regelVoorDienst` laat het kantoor per dienst autonomie aanzetten; standaard
 * geldt de veilige default-deny-regel (→ escaleren). De audit-ketting wordt
 * doorheen alle opzoekingen doorgegeven en teruggegeven.
 */
export async function voerOpzoekingenUit(args: {
  dossier: Dossier;
  dossierRef: string;
  tijdstip: string;
  zekerheid: Zekerheid;
  regelVoorDienst?: (dienst: ConnectorDienst) => AutonomieRegel;
  auditKetting?: readonly AuditRegel[];
  registraties?: readonly ConnectorRegistratie[];
}): Promise<OpzoekingenResultaat> {
  const { dossier, dossierRef, tijdstip, zekerheid, regelVoorDienst, auditKetting = [], registraties } = args;

  const perDienst: OpzoekingUitkomst[] = [];
  const nietAangesloten: ConnectorDienst[] = [];
  let ketting: readonly AuditRegel[] = auditKetting;

  for (const dienst of vereisteOpzoekingen(dossier)) {
    const connector = connectorVoorDienst(dienst, registraties);
    if (!connector) {
      nietAangesloten.push(dienst);
      continue;
    }
    const regel = regelVoorDienst?.(dienst) ?? veiligeStandaardregel(`opzoeking-${dienst}`, "laag");
    const uitvoering = await voerUitMetPoort({
      connector,
      aanvraag: { dienst, idempotentiesleutel: `${dossierRef}/${dienst}`, payload: {} },
      regel,
      zekerheid,
      auditKetting: ketting,
      dossierRef,
      tijdstip,
    });
    ketting = uitvoering.auditKetting;
    perDienst.push({ dienst, uitkomst: uitvoering.uitkomst, antwoord: uitvoering.antwoord, reden: uitvoering.reden });
  }

  return { perDienst, nietAangesloten, auditKetting: [...ketting] };
}
