// ── Dossier → autonoom klaargemaakte modelmails ──────────────────────────────
// Tweede pijler van het Einddoel (na het ontwerpdocument): leidt uit een
// dossier af welke modelmail(s) relevant zijn en vult ze meteen in met de
// gekende dossiergegevens. Net als bij stelOntwerpakteSamenAutonoom (de
// ontwerpakte) blijft het resultaat een werkdocument: alles wat niet met
// zekerheid kon worden ingevuld, komt in `onzekerheden` in plaats van
// stilzwijgend te worden ingevuld of weggelaten.
//
// Kernprincipe (AGENTS.md): nooit doen-alsof-zeker. De functie kiest de
// relevante categorieën op basis van het dossiertype, maar laat de notaris
// vrij welke concrete mail(s) effectief worden verstuurd.

import type { Dossier, Dossiertype, DossierStatus } from "./types";
import { dossierNaarModelbriefWaarden } from "./modelbriefParameters";
import { KANTOOR, type Kantoor } from "@/data/kantoor";
import {
  vulModelbriefIn,
  bepaalOntvangerRol,
  type Modelbrief,
  type BriefCategorie,
  type BriefTaal,
  type IngevuldeBrief,
} from "@/data/modelbrieven";

/**
 * Relevante modelbrief-categorieën per dossiertype. Bewust conservatief: enkel
 * categorieën waarvan met zekerheid kan worden gezegd dat ze bij dit
 * dossiertype horen. Een leeg resultaat betekent dat de notaris zelf de
 * passende categorie moet kiezen (geen blinde gok).
 *
 * Met een `status` erbij wordt de lijst bovendien gefilterd op dossierfase:
 * "akteontwerp"-mails (ontwerp + afrekening versturen) zijn pas zinvol vanaf
 * het moment dat er effectief een ontwerp in opmaak is — vroeger voorstellen
 * zou de notaris een mail laten versturen die nog niets heeft om te tonen.
 * Zonder `status` blijft het gedrag ongewijzigd (alle categorieën van het
 * dossiertype), zodat bestaande aanroepen die enkel het dossiertype kennen
 * blijven werken.
 */
export function relevanteBriefCategorieen(
  dossiertype: Dossiertype,
  status?: DossierStatus
): BriefCategorie[] {
  const categorieen = bepaalBasisCategorieen(dossiertype);
  if (!status) return categorieen;

  const ontwerpNogNietGestart = status === "compromis-ontvangen" || status === "opzoekingen-lopend";
  return ontwerpNogNietGestart ? categorieen.filter((c) => c !== "akteontwerp") : categorieen;
}

function bepaalBasisCategorieen(dossiertype: Dossiertype): BriefCategorie[] {
  switch (dossiertype) {
    case "verkoop-met-krediet":
      return ["verkoop", "akteontwerp", "betaling", "kredietdossier"];
    case "verkoop-zonder-krediet":
      return ["verkoop", "akteontwerp", "betaling"];
    case "schenking":
      return ["schenking", "akteontwerp"];
    case "nalatenschap":
      return ["nalatenschap"];
    case "aanpassing-statuten-vennootschap":
      return ["vennootschappen"];
    case "keuzetestament":
    case "testament-gezinswoning":
      return ["testament"];
    default: {
      // Exhaustiviteitscontrole: faalt de compilatie hier, dan is er een
      // dossiertype bijgekomen zonder mapping in deze functie.
      const _onbekend: never = dossiertype;
      void _onbekend;
      return [];
    }
  }
}

/**
 * Vult de generieke aanhefnaam {{naam}} in op basis van de ontvanger van de
 * mail: enkel wanneer de mail rechtstreeks aan de koper- of verkoper-cliënt is
 * gericht. Voor tussenpersonen (confrater, notaris, makelaar, bank, fiscus)
 * blijft {{naam}} open — hun naam staat niet in het dossier.
 */
export function mailWaardenVoorOntvanger(
  ontvanger: string,
  waarden: Record<string, string>
): Record<string, string> {
  const rol = bepaalOntvangerRol(ontvanger);
  if (rol === "client-verkoper" && waarden.naam_verkoper) return { ...waarden, naam: waarden.naam_verkoper };
  if (rol === "client-koper" && waarden.naam_koper) return { ...waarden, naam: waarden.naam_koper };
  return waarden;
}

/** Eén begeleidende brief (titel + ingevulde inhoud) voor het werkdossier. */
export interface BegeleidendeBrief {
  titel: string;
  ingevuld: IngevuldeBrief;
}

/**
 * Standaard begeleidende brieven voor een verkoop-werkdossier wanneer de
 * aanroeper er zelf geen meegeeft: één brief aan de cliënt (koper) in de
 * documenttaal en één aan de confrater-notaris in diens regiotaal. Zo bevat het
 * werkdossier altijd de begeleidende correspondentie. Voor andere akteTypes
 * leeg (de notaris kiest dan zelf de passende correspondentie).
 */
export function standaardBegeleidendeBrieven(
  akteType: string,
  brieven: Modelbrief[],
  waarden: Record<string, string>,
  docTaal: BriefTaal,
  confraterTaal: BriefTaal
): BegeleidendeBrief[] {
  if (!/verkoop/i.test(akteType)) return [];
  const verkoop = brieven.filter((b) => b.categorie === "verkoop");
  const client = verkoop.find((b) => (b.taal ?? "nl") === docTaal && /koper \(cli/.test(b.ontvanger.toLowerCase()));
  const confrater =
    verkoop.find((b) => (b.taal ?? "nl") === confraterTaal && /confrater/.test(b.ontvanger.toLowerCase())) ??
    verkoop.find((b) => (b.taal ?? "nl") === confraterTaal && /notaris/.test(b.ontvanger.toLowerCase()));
  const resultaat: BegeleidendeBrief[] = [];
  for (const b of [client, confrater]) {
    if (!b) continue;
    resultaat.push({ titel: b.titel, ingevuld: vulModelbriefIn(b, mailWaardenVoorOntvanger(b.ontvanger, waarden)) });
  }
  return resultaat;
}

/** Eén autonoom ingevulde modelmail met de onzekerheden die nog open staan. */
export interface AutonomeModelmail {
  brief: Modelbrief;
  ingevuld: IngevuldeBrief;
  onzekerheden: string[];
}

/** Resultaat van het autonoom klaarmaken van de modelmails voor een dossier. */
export interface AutonomeModelmails {
  /** De categorieën die als relevant voor dit dossiertype werden bepaald. */
  categorieen: BriefCategorie[];
  /** Per relevante modelmail het ingevulde werkdocument + onzekerheden. */
  mails: AutonomeModelmail[];
  /** Onzekerheden op het niveau van de hele selectie (bv. geen enkele mail gevonden). */
  onzekerheden: string[];
}

/**
 * Stelt autonoom de relevante modelmails samen voor een dossier: bepaalt de
 * relevante categorieën (uit het dossiertype), zoekt de bijbehorende
 * modelbrieven in de aangeleverde bibliotheek (seed + gebruikersbrieven) in de
 * gevraagde taal en vult ze in met de gekende dossiergegevens. Net als bij de
 * ontwerpakte spreekt deze functie zelf geen opslag aan — de aanroeper levert
 * `brieven` aan.
 */
/** Is deze brief gericht aan de confrater-notaris (of zijn kantoor)? */
function isAanConfrater(ontvanger: string): boolean {
  return bepaalOntvangerRol(ontvanger) === "confrater";
}

export function stelModelmailsSamenAutonoom(
  dossier: Dossier,
  brieven: Modelbrief[],
  taal: BriefTaal = "nl",
  kantoor: Kantoor = KANTOOR,
  /**
   * Taal van de brief aan de confrater-notaris, los van de documenttaal: een
   * notaris in Vlaanderen schrijf je in het NL aan, in Wallonië in het FR; in
   * Brussel volgt de brief de taal van het model. Ontbreekt = `taal`.
   */
  confraterTaal: BriefTaal = taal
): AutonomeModelmails {
  const categorieen = relevanteBriefCategorieen(dossier.dossiertype, dossier.status);
  const onzekerheden: string[] = [];

  if (categorieen.length === 0) {
    onzekerheden.push(
      "Geen modelmail-categorie eenduidig af te leiden uit het dossiertype — de notaris kiest zelf de passende correspondentie."
    );
    return { categorieen, mails: [], onzekerheden };
  }

  const waarden = dossierNaarModelbriefWaarden(dossier, kantoor);
  // De brief aan de confrater volgt confraterTaal (regio van de confrater); alle
  // andere brieven volgen de documenttaal.
  const passend = brieven.filter((b) => {
    if (!categorieen.includes(b.categorie)) return false;
    const gewenst = isAanConfrater(b.ontvanger) ? confraterTaal : taal;
    return (b.taal ?? "nl") === gewenst;
  });

  if (passend.length === 0) {
    onzekerheden.push(
      `Geen modelmail in de bibliotheek voor de relevante categorie(ën) (${categorieen.join(", ")}) in taal "${taal}".`
    );
    return { categorieen, mails: [], onzekerheden };
  }

  const mails: AutonomeModelmail[] = passend.map((brief) => {
    const ingevuld = vulModelbriefIn(brief, mailWaardenVoorOntvanger(brief.ontvanger, waarden));
    const volledig = `${ingevuld.onderwerp}\n${ingevuld.tekst}`;
    const aanTeVullen = [
      ...new Set([...volledig.matchAll(/\[AAN TE VULLEN: ([^\]]+)\]/g)].map((m) => m[1])),
    ];
    const mailOnzekerheden = aanTeVullen.length
      ? [`Niet uit het dossier afleidbare parameters: ${aanTeVullen.join(", ")}.`]
      : [];
    return { brief, ingevuld, onzekerheden: mailOnzekerheden };
  });

  return { categorieen, mails, onzekerheden };
}
