import type { BriefTaal, Modelbrief, OntvangerRol } from "./types";
import { extraheerParameters as extraheerParameterNamen } from "@/data/modeldocumenten";

// ── Samenstellen en invullen ─────────────────────────────────────────────────
// Pure functies (geen React, geen browser-API's) die modelbrieven omzetten
// naar een verzendbare onderwerp+tekst-combinatie.

/**
 * Leidt de gestructureerde geadresseerde-rol af uit het vrije `ontvanger`-
 * label van een modelbrief (bv. "Koper (cliënt)", "confrater (verkoper)").
 * Eén bron van waarheid voor deze classificatie — vervangt de losse,
 * onderling licht verschillende regexen die voorheen verspreid stonden over
 * `isAanConfrater`/`mailWaardenVoorOntvanger`/`standaardBegeleidendeBrieven`
 * (`lib/dossier/modelmails.ts`). Volgorde is betekenisvol: "verkoper" moet
 * vóór "koper" gecontroleerd worden (het woord "koper" zit als deelstring in
 * "verkoper"), en tussenpersonen (confrater/bank/makelaar/fiscus/bieder) vóór
 * de generieke cliëntherkenning.
 */
export function bepaalOntvangerRol(ontvanger: string): OntvangerRol {
  const o = ontvanger.toLowerCase();
  if (/spf|finances/.test(o)) return "fiscus";
  if (/confrater|notaris|minuuthouder/.test(o)) return "confrater";
  if (/bank|banque/.test(o)) return "bank";
  if (/makelaar|bemiddelaar/.test(o)) return "makelaar";
  if (/bieder|offrant/.test(o)) return "bieder";
  if (/verkoper/.test(o)) return "client-verkoper";
  if (/koper|acquéreur|buyer/.test(o)) return "client-koper";
  if (/cli[eë]nt|client/.test(o)) return "client-overig";
  return "overig";
}

/** Alle {{parameter}}-namen die in onderwerp, tekst, varianten en slot voorkomen. */
export function verzamelParameterNamen(brief: Modelbrief): string[] {
  return extraheerParameterNamen(
    brief.onderwerp,
    brief.tekst,
    ...brief.varianten.map((v) => v.tekst),
    brief.slot ?? ""
  );
}

function vervangParameters(tekst: string, waarden: Record<string, string>): string {
  return tekst.replace(/\{\{([^}]+)\}\}/g, (_, naam: string) => {
    const waarde = waarden[naam.trim()]?.trim();
    return waarde || `[AAN TE VULLEN: ${naam.trim()}]`;
  });
}

/** Resultaat van het invullen van een modelbrief: klaar voor een e-mailclient. */
export interface IngevuldeBrief {
  onderwerp: string;
  tekst: string;
  bijlagen: string[];
  /** Gestructureerde geadresseerde-rol, afgeleid uit `Modelbrief.ontvanger`. */
  rol: OntvangerRol;
}

/**
 * Vult een modelbrief in: parameters vervangen door waarden of
 * [AAN TE VULLEN: …], en enkel de gekozen varianten toegevoegd na de
 * basistekst.
 */
export function vulModelbriefIn(
  brief: Modelbrief,
  waarden: Record<string, string>,
  variantIds?: string[]
): IngevuldeBrief {
  const onderwerp = vervangParameters(brief.onderwerp, waarden);
  const delen: string[] = [];
  if (brief.tekst.trim()) delen.push(vervangParameters(brief.tekst.trim(), waarden));

  const varianten = variantIds
    ? brief.varianten.filter((v) => variantIds.includes(v.id))
    : brief.varianten;
  for (const variant of varianten) {
    delen.push(vervangParameters(variant.tekst.trim(), waarden));
  }
  if (brief.slot?.trim()) delen.push(vervangParameters(brief.slot.trim(), waarden));

  return { onderwerp, tekst: delen.join("\n\n"), bijlagen: brief.bijlagen ?? [], rol: bepaalOntvangerRol(brief.ontvanger) };
}

/**
 * Groepeert een modelbrief met haar anderstalige vertalingen (NL/FR/EN),
 * ongeacht welk lid van de groep als startpunt werd meegegeven: elke
 * vertaling wijst via `vertalingVanId` naar de NL-bronbrief, dus zowel de
 * bron zelf als elke vertaling herkent de andere leden van dezelfde groep.
 * Parameternamen en varianten-id's zijn per conventie identiek over de talen
 * heen (zie de brieven-seeds), zodat één gedeelde invulstaat alle
 * taalversies tegelijk kan aandrijven.
 */
export function vindModelbriefGroep(
  brief: Modelbrief,
  alleBrieven: Modelbrief[]
): Partial<Record<BriefTaal, Modelbrief>> {
  const bronId = brief.vertalingVanId ?? brief.id;
  const groep: Partial<Record<BriefTaal, Modelbrief>> = {};
  for (const b of alleBrieven) {
    if (b.id === bronId || b.vertalingVanId === bronId) groep[b.taal] = b;
  }
  return groep;
}
