// ── Stap 4: autonoom opstellen van de ontwerpakte ────────────────────────────
// Orkestreert stap 1 (akteType-detectie), stap 2 (parameter-/hypothesemapping)
// en de bestaande generatiefunctie tot één pure stap: Dossier in, een
// (voorlopig) ingevuld werkdocument + onzekerhedenlijst uit. Geen UI-state,
// geen side effects — de aanroeper (UI-pagina of MCP-tool) levert de
// gecombineerde seed+gebruikersbibliotheek aan en doet er verder mee wat
// nodig is (tonen, exporteren, doorsturen).
//
// Kernprincipe (AGENTS.md): het resultaat is en blijft een werkdocument. Elke
// keuze die niet met zekerheid uit het dossier kon worden afgeleid, komt in
// `onzekerheden` terecht in plaats van stilzwijgend te worden ingevuld of
// weggelaten.

import type { Dossier } from "./types";
import type { Gewest } from "@/lib/context/gewest";
import { bepaalAkteType, type AkteTypeKeuze } from "./akteType";
import { dossierNaarKeuzes, dossierNaarParameterwaarden, dossierNaarPartijHerhalingen } from "./parameters";
import { genereerDocument, pasKeuzesToe, verwijderOpmaakMarkers, type Modeldocument, type Modelonderdeel, type Taal } from "@/data/modeldocumenten";
import { KANTOOR, type Kantoor } from "@/data/kantoor";

/** Resultaat van het autonoom opstellen van een ontwerpakte uit een dossier. */
export interface AutonomeOntwerpakte {
  akteTypeKeuze: AkteTypeKeuze;
  /** Het gevonden modeldocument voor het gekozen akteType; ontbreekt bij een hiaat in de bibliotheek. */
  model?: Modeldocument;
  /** Het ingevulde werkdocument; ontbreekt wanneer er geen akteType of model kon worden bepaald. */
  tekst?: string;
  /**
   * Alles wat de notaris vóór gebruik moet beoordelen: een onzekere
   * akteType-keuze, een ontbrekend model, niet uit het dossier afleidbare
   * parameters, of nog open hypothesekeuzes in de gegenereerde tekst.
   */
  onzekerheden: string[];
}

/**
 * Stelt autonoom een ontwerpakte samen uit een dossier: bepaalt het
 * akteType (stap 1), zoekt het bijbehorende model, leidt de hypothesekeuzes
 * en parameterwaarden af (stap 2) en genereert het werkdocument. `modellen`
 * en `onderdelen` zijn de gecombineerde seed+gebruikersbibliotheek (zoals
 * elders al via `combineerMetSeed` wordt samengesteld) en worden door de
 * aanroeper meegegeven, zodat deze functie zelf geen opslag aanspreekt.
 */
export function stelOntwerpakteSamenAutonoom(
  dossier: Dossier,
  modellen: Modeldocument[],
  onderdelen: Modelonderdeel[],
  gewest: Gewest,
  kantoor: Kantoor = KANTOOR,
  taal: Taal = "nl"
): AutonomeOntwerpakte {
  const akteTypeKeuze = bepaalAkteType(dossier);
  const onzekerheden: string[] = [];

  if (akteTypeKeuze.zekerheid === "onduidelijk") {
    const alternatieven = akteTypeKeuze.alternatieven?.length
      ? ` Alternatieven: ${akteTypeKeuze.alternatieven.join(", ")}.`
      : "";
    onzekerheden.push(`AkteType niet eenduidig: ${akteTypeKeuze.reden}${alternatieven}`);
  }

  if (!akteTypeKeuze.akteType) {
    return { akteTypeKeuze, onzekerheden };
  }

  // Kies het model in de gevraagde taal (de taal van de gebruiker, tenzij het
  // dossier een andere taal duidelijk aangeeft). Bestaat het niet in die taal,
  // dan valt het terug op het Nederlandstalige model, met een melding.
  const inTaal = modellen.find((m) => m.akteType === akteTypeKeuze.akteType && (m.taal ?? "nl") === taal);
  const model = inTaal ?? modellen.find((m) => m.akteType === akteTypeKeuze.akteType && (m.taal ?? "nl") === "nl");
  if (model && taal !== "nl" && !inTaal) {
    onzekerheden.push(
      `Geen ${taal.toUpperCase()}-model gevonden voor "${akteTypeKeuze.akteType}"; het Nederlandstalige model is gebruikt. Een vertaling toevoegen aan de bibliotheek is aangewezen.`
    );
  }
  if (!model) {
    onzekerheden.push(
      `Geen modeldocument gevonden voor akteType "${akteTypeKeuze.akteType}" — een wijzigingsvoorstel om dit model toe te voegen aan de bibliotheek is nodig.`
    );
    return { akteTypeKeuze, onzekerheden };
  }

  const keuzes = pasKeuzesToe(model, dossierNaarKeuzes(dossier, gewest));
  // De daadwerkelijke taal van het gekozen model (kan, bij ontbrekend FR-model,
  // op NL terugvallen) bepaalt de taalformattering van de waarden (datums,
  // rangtelwoorden, identiteitsblokken) én de identiteitsclausule per partij.
  const modelTaal = model.taal ?? "nl";
  const waarden = dossierNaarParameterwaarden(dossier, kantoor, onderdelen, modelTaal);
  const partijHerhalingen = dossierNaarPartijHerhalingen(dossier, modelTaal);
  const tekst = genereerDocument(model, onderdelen, keuzes, waarden, partijHerhalingen);

  const aanTeVullen = [...new Set([...tekst.matchAll(/\[AAN TE VULLEN: ([^\]]+)\]/g)].map((m) => m[1]))];
  if (aanTeVullen.length > 0) {
    onzekerheden.push(`Niet uit het dossier afleidbare parameters: ${aanTeVullen.join(", ")}.`);
  }

  if (tekst.includes("[KIES DE TOEPASSELIJKE HYPOTHESE EN SCHRAP DE OVERIGE:]")) {
    onzekerheden.push(
      "Eén of meer onderdelen hebben nog een open hypothesekeuze die de notaris zelf moet maken."
    );
  }

  // Voor de UI-preview de vette-tekst-markers verwijderen (die zijn enkel voor de
  // Word-render); de .docx wordt apart gegenereerd en behoudt de opmaak.
  return { akteTypeKeuze, model, tekst: verwijderOpmaakMarkers(tekst), onzekerheden };
}
