// ── AUT-O1 · Zekerheids- & escalatiemodel (autonomie-besturing, laag 7) ──────
// De bovenste besturingslaag van de autonomie-roadmap (AUTONOMIE-ROADMAP.md):
// beslist, per concrete handeling, of Notary.AI ze AUTONOOM mag uitvoeren dan
// wel moet ESCALEREN naar de notaris — of dat ze VERBODEN is (het ambtelijk
// voorbehoud). Dit is de bewaakte kern; het aansluiten van echte tier-3-
// handelingen (opzoekingen aanvragen, mails versturen, neerleggingen,
// doorstortingen) gebeurt in de opvolgwerven (AUT-S4/S5/S7/S8), telkens via
// `beslisEscalatie` — nooit door die poort te omzeilen.
//
// ── Ontwerpbeslissingen (de dragende Opus-keuzes) ───────────────────────────
// 1. ZEKERHEID IS AFGELEID, NIET GEASSERTEERD. Een los "95 %"-getal van een
//    model is niet betrouwbaar genoeg om een ONOMKEERBARE handeling op te
//    bouwen. `bepaalZekerheid` leidt het niveau daarom af uit CONTROLEERBARE
//    gronden (zijn alle nodige feiten er met gezaghebbende bron? geen
//    onopgeloste tegenstrijdigheid? geen openstaande keuze? geen gedivergeerde
//    parallel?). Een modelinschatting mag hoogstens ÉÉN grond zijn, nooit de
//    enige.
// 2. DEFAULT-DENY VOOR NAAR-BUITEN-HANDELEN. Een tier-3-handeling is enkel
//    autonoom als (a) het kantoor dit handelingstype uitdrukkelijk autonoom
//    heeft aangezet én (b) de gemeten zekerheid het door het kantoor vereiste
//    minimumniveau haalt. Alles wat niet expliciet is toegestaan, escaleert.
//    Een onbekend/onbeschreven handelingstype escaleert (nooit "gokken en
//    doen").
// 3. HET AMBTELIJK VOORBEHOUD IS ABSOLUUT. Een handeling van tier "ambtelijk"
//    (verlijden, wilscontrole, voorlezing, rechtsweigering) levert ALTIJD
//    "verboden" op, ongeacht zekerheid of kantoorbeleid — de wettelijke
//    bovengrens uit AGENTS.md/AUTONOMIE-ROADMAP.md.
//
// Puur en deterministisch: geen I/O, geen tijd/toeval — zelfde invoer, zelfde
// besluit. De verantwoording (WELKE gronden, WELK beleid) reist mee in het
// besluit, klaar voor de audit-trail (AUT-O2).

import type { WerkdossierOnzekerheid } from "./werkdossier";

/** De vier handelingsregimes uit AGENTS.md (§ "drie handelingsregimes" + het
 * ambtelijk voorbehoud). */
export type Handelingstier =
  | "genereren" // tier 1: werkdocument, geen gedeelde data — vrij autonoom
  | "muteren-bibliotheek" // tier 2: altijd via wijzigingsvoorstel
  | "handelen-extern" // tier 3: naar buiten/onomkeerbaar — zekerheidsgestuurd
  | "ambtelijk"; // voorbehouden aan de notaris — nooit geautomatiseerd

/** Onomkeerbaarheid/gewicht van een externe handeling; louter informatief voor
 * het kantoorbeleid (een strenger minimumniveau bij hogere impact). */
export type Handelingsimpact = "laag" | "midden" | "hoog";

/** Zekerheidsniveau, afgeleid uit de gronden (niet los geasserteerd). */
export type Zekerheidsniveau = "zeker" | "waarschijnlijk" | "onzeker";

const NIVEAU_ORDE: Record<Zekerheidsniveau, number> = { onzeker: 0, waarschijnlijk: 1, zeker: 2 };

/** Eén controleerbare grond die de zekerheid onderbouwt of ondergraaft. */
export interface Zekerheidsgrond {
  omschrijving: string;
  /** true = ondersteunt de zekerheid; false = ondergraaft ze (bv. een openstaande onzekerheid). */
  positief: boolean;
  /**
   * Enkel bij een negatieve grond: deze grond alléén verlaagt de zekerheid
   * meteen tot "onzeker" (bv. een onopgeloste tegenstrijdigheid tussen bronnen
   * of een gedivergeerde parallelclausule). Niet-blokkerende negatieve gronden
   * verlagen trapsgewijs.
   */
  blokkerend?: boolean;
}

/** Afgeleide zekerheid: het niveau plus de gronden waarop het steunt (verantwoording). */
export interface Zekerheid {
  niveau: Zekerheidsniveau;
  gronden: Zekerheidsgrond[];
}

/**
 * Leidt het zekerheidsniveau af uit de gronden. Regels (bewust conservatief):
 * - géén gronden → "onzeker" (geen basis = geen vertrouwen; default-deny);
 * - een blokkerende negatieve grond → "onzeker";
 * - anders: geen negatieve gronden → "zeker"; één → "waarschijnlijk";
 *   twee of meer → "onzeker".
 */
export function bepaalZekerheid(gronden: Zekerheidsgrond[]): Zekerheid {
  if (gronden.length === 0) return { niveau: "onzeker", gronden };
  const negatief = gronden.filter((g) => !g.positief);
  if (negatief.some((g) => g.blokkerend)) return { niveau: "onzeker", gronden };
  const niveau: Zekerheidsniveau = negatief.length === 0 ? "zeker" : negatief.length === 1 ? "waarschijnlijk" : "onzeker";
  return { niveau, gronden };
}

/**
 * Zet de openstaande onzekerheden van een werkdossier om in negatieve gronden,
 * zodat de bestaande onzekerhedenlus (werkdossier.ts) rechtstreeks de zekerheid
 * van een tier-3-handeling voedt. Elke onzekerheid is een reden om NIET blind
 * autonoom te handelen.
 */
export function grondenUitOnzekerheden(onzekerheden: WerkdossierOnzekerheid[]): Zekerheidsgrond[] {
  return onzekerheden.map((o) => ({
    omschrijving: `${o.pijler}: ${o.boodschap}`,
    positief: false,
  }));
}

/** Kantoorbeleid voor één handelingstype: mag het autonoom, en zo ja vanaf welk niveau? */
export interface AutonomieRegel {
  /** Uniek handelingstype, bv. "opzoeking-hypothecaire-staat", "mail-versturen". */
  handelingstype: string;
  tier: Handelingstier;
  impact: Handelingsimpact;
  /** Heeft het kantoor autonomie voor dit type uitdrukkelijk aangezet? (tier 3) */
  autonoomToegestaan: boolean;
  /** Vereist minimum-zekerheidsniveau voor een autonome uitvoering (tier 3). */
  minimumNiveau: Zekerheidsniveau;
}

/** De uitkomst van de escalatiebeslissing. */
export type Beslissing =
  | "autonoom" // Notary.AI mag de handeling zelf uitvoeren
  | "escaleren" // leg voor aan de notaris (of, tier 2, dien als wijzigingsvoorstel in)
  | "verboden"; // ambtelijk voorbehoud — nooit door software

/** Het besluit mét verantwoording (klaar voor de audit-trail, AUT-O2). */
export interface Escalatiebesluit {
  beslissing: Beslissing;
  reden: string;
  /** Het niveau dat aan het besluit ten grondslag lag. */
  zekerheidsniveau: Zekerheidsniveau;
}

/** Haalt het actuele niveau het vereiste minimum? */
function voldoetNiveau(actueel: Zekerheidsniveau, minimum: Zekerheidsniveau): boolean {
  return NIVEAU_ORDE[actueel] >= NIVEAU_ORDE[minimum];
}

/**
 * Beslist of een handeling autonoom mag, moet escaleren, of verboden is.
 * Zie de ontwerpbeslissingen bovenaan: het ambtelijk voorbehoud is absoluut,
 * tier 1 is vrij, tier 2 gaat altijd via een voorstel (= escaleren), en tier 3
 * is default-deny + zekerheidsgestuurd.
 */
export function beslisEscalatie(regel: AutonomieRegel, zekerheid: Zekerheid): Escalatiebesluit {
  const niveau = zekerheid.niveau;
  const met = (beslissing: Beslissing, reden: string): Escalatiebesluit => ({ beslissing, reden, zekerheidsniveau: niveau });

  switch (regel.tier) {
    case "ambtelijk":
      return met(
        "verboden",
        "Ambtelijk voorbehoud: verlijden/wilscontrole/voorlezing/rechtsweigering blijven bij wet aan de notaris — nooit geautomatiseerd."
      );
    case "genereren":
      return met("autonoom", "Tier 1 (genereren/berekenen/opzoeken): werkdocument zonder gedeelde mutatie — vrij autonoom.");
    case "muteren-bibliotheek":
      return met("escaleren", "Tier 2 (bibliotheekmutatie): altijd via een wijzigingsvoorstel dat de notaris goedkeurt.");
    case "handelen-extern": {
      if (!regel.autonoomToegestaan) {
        return met(
          "escaleren",
          `Tier 3 (${regel.handelingstype}): het kantoor heeft autonomie voor dit handelingstype niet aangezet — escaleren.`
        );
      }
      if (!voldoetNiveau(niveau, regel.minimumNiveau)) {
        return met(
          "escaleren",
          `Tier 3 (${regel.handelingstype}, impact ${regel.impact}): gemeten zekerheid "${niveau}" haalt het vereiste minimum "${regel.minimumNiveau}" niet — escaleren.`
        );
      }
      return met(
        "autonoom",
        `Tier 3 (${regel.handelingstype}): autonomie toegestaan en zekerheid "${niveau}" voldoet aan minimum "${regel.minimumNiveau}".`
      );
    }
  }
}

/**
 * Veilig standaardbeleid voor een tier-3-handelingstype: autonomie UIT
 * (default-deny) en, mocht ze aangezet worden, het strengste minimum voor de
 * hoogste impact. Een kantoor vertrekt hiervan en zet bewust, per type, de
 * autonomie aan met het gewenste minimumniveau.
 */
export function veiligeStandaardregel(handelingstype: string, impact: Handelingsimpact): AutonomieRegel {
  return {
    handelingstype,
    tier: "handelen-extern",
    impact,
    autonoomToegestaan: false,
    minimumNiveau: impact === "hoog" ? "zeker" : impact === "midden" ? "zeker" : "waarschijnlijk",
  };
}
