// ── Module "Modeldocumenten" — types ─────────────────────────────────────────
// Evolutieve bibliotheek: herbruikbare modelonderdelen (clausules) worden
// samengesteld tot volledige modeldocumenten (verkoopakte, compromis,
// volmacht, huwelijksovereenkomst, …). Onderdelen bevatten zoveel mogelijk
// hypotheses als varianten; bij gebruik worden parameters ingevuld en
// niet-toepasselijke varianten/onderdelen geschrapt.

/** Rubriek van een modelonderdeel, voor filtering en ordening. */
export type OnderdeelCategorie =
  | "partijen"
  | "goed"
  | "prijs"
  | "voorwaarden"
  | "attesten"
  | "bijzonder"
  | "vorm"
  | "lastgeving"
  | "vennootschap"
  | "erfrecht"
  | "schenking";

export const onderdeelCategorieLabels: Record<OnderdeelCategorie, string> = {
  partijen: "Partijen & vertegenwoordiging",
  goed: "Onroerend goed & titel",
  prijs: "Prijs & betaling",
  voorwaarden: "Voorwaarden & modaliteiten",
  attesten: "Attesten & informatieplichten",
  bijzonder: "Bijzondere regimes",
  vorm: "Vorm- & slotbepalingen",
  lastgeving: "Lastgeving & volmachten (zorgvolmacht)",
  vennootschap: "Vennootschappen — statuten & algemene vergadering",
  erfrecht: "Erfrecht & uiterste wilsbeschikkingen",
  schenking: "Schenking",
};

/**
 * Hoofdthema, identiek aan de mappenstructuur van "Modellen CD" op de
 * kantoorserver. Elk modeldocument hoort bij precies één thema; de seeds
 * staan per thema in een eigen bestand onder data/modeldocumenten/modellen/.
 */
export type Hoofdthema =
  | "algemeen"
  | "familie"
  | "vastgoed"
  | "vennootschappen"
  | "fiscaal";

export const hoofdthemaLabels: Record<Hoofdthema, string> = {
  algemeen: "0. Algemeen",
  familie: "1. Familie",
  vastgoed: "2. Vastgoed",
  vennootschappen: "3. Vennootschappen",
  fiscaal: "4. Fiscaal",
};

/**
 * Soort document volgens de naamconventies van de kantoormodellen
 * (INSTRUCTIES_MODELLEN_CD): MOD = volwaardig model met hypotheses en
 * reminders; VB = voorbeeld, mogelijk onvolledig — kritisch bekijken;
 * MODCL/VBCL = losse (voorbeeld)clausules; FORM/CHECKLIST/INFO/…BRIEF =
 * ondersteunende documenten.
 */
export type DocumentSoort =
  | "MOD"
  | "VB"
  | "FORM"
  | "CHECKLIST"
  | "INFO"
  | "MODCL"
  | "VBCL"
  | "MODBRIEF"
  | "VBBRIEF";

export const documentSoortLabels: Record<DocumentSoort, string> = {
  MOD: "Model",
  VB: "Voorbeeld (onvolledig — kritisch bekijken)",
  FORM: "Formulier",
  CHECKLIST: "Checklist",
  INFO: "Infofiche",
  MODCL: "Modelclausule(s)",
  VBCL: "Voorbeeldclausule(s) — ter inspiratie",
  MODBRIEF: "Modelbrief/-mail",
  VBBRIEF: "Voorbeeldbrief/-mail — ter inspiratie",
};

/** Taal van een clausule of model. Vertalingen zijn aparte items, gelinkt via vertalingVanId. */
export type Taal = "nl" | "fr";

export const taalLabels: Record<Taal, string> = {
  nl: "Nederlands",
  fr: "Frans",
};

/**
 * Status van het juridisch nazicht van een clausule tegenover de huidige
 * (evoluerende) wetgeving. "na_te_kijken" = vermoedelijk gedeeltelijk
 * achterhaald of recent gewijzigde regelgeving; "verouderd" = bevat regels
 * die niet meer gelden en mag enkel met correctie worden gebruikt.
 */
export type NazichtStatus = "actueel" | "na_te_kijken" | "verouderd";

export const nazichtStatusLabels: Record<NazichtStatus, string> = {
  actueel: "Actueel",
  na_te_kijken: "Na te kijken",
  verouderd: "Verouderd",
};

/** Juridisch nazicht: wanneer laatst gecontroleerd en wat de aandachtspunten zijn. */
export interface Nazicht {
  status: NazichtStatus;
  /** Datum van het laatste nazicht (ISO, jjjj-mm-dd). */
  datum: string;
  /** Wat te controleren vóór gebruik of bij het volgende nazicht. */
  aandachtspunten?: string;
}

/** In te vullen parameter, in de tekst genoteerd als {{naam}}. */
export interface ModelParameter {
  naam: string;
  omschrijving: string;
  voorbeeld?: string;
}

/**
 * Hypothese-variant van een onderdeel: bij gebruik wordt de toepasselijke
 * variant behouden en worden de overige geschrapt.
 */
export interface ModelVariant {
  id: string;
  hypothese: string;
  tekst: string;
  /**
   * Toelichting bij deze variant uit de brontekst (bv. een "Toelichting bij
   * de clausule"/"Commentaire relatif à la clause"-sectie die vóór het
   * eigenlijke clausulevoorstel staat): nooit in `tekst` opnemen (dat is
   * uitsluitend de in te voegen clausule), wel hier bewaren zodat geen
   * juridische informatie uit de bron verloren gaat.
   */
  toelichting?: string;
}

/** Herbruikbaar bouwblok (clausule) voor meerdere modeltypes. */
export interface Modelonderdeel {
  id: string;
  titel: string;
  categorie: OnderdeelCategorie;
  omschrijving: string;
  /** Basistekst met {{parameter}}-placeholders; leeg als alles in varianten zit. */
  tekst: string;
  /**
   * Toelichting bij het onderdeel als geheel uit de brontekst — zelfde
   * regel als ModelVariant.toelichting: nooit in `tekst`, wel hier bewaren.
   */
  toelichting?: string;
  /**
   * Handleiding voor de (AI-)agent die dit onderdeel in een dossier verwerkt:
   * op basis van welk feit/kenmerk de juiste variant gekozen wordt, welke
   * brondocumenten daarvoor nodig zijn, en gekende valkuilen — zodat een
   * agent zonder juridische achtergrond zich zo weinig mogelijk vergist bij
   * het kiezen van de hypothese en het invullen van de parameters. Geen
   * verplichting met terugwerkende kracht; wel in te vullen bij elk nieuw
   * onderdeel en aan te vullen zodra een fout hiermee had kunnen worden
   * vermeden.
   */
  agentwenken?: string;
  varianten: ModelVariant[];
  parameters: ModelParameter[];
  /** Modeltypes waarin dit onderdeel bruikbaar is (vrije labels). */
  toepasbaarOp: string[];
  /** Hoofdthema (kantoormap); ontbreekt = themaoverstijgend herbruikbaar. */
  thema?: Hoofdthema;
  /** Soort volgens de kantoorconventies; ontbreekt = "MODCL". */
  soort?: DocumentSoort;
  /** Herkomst: Fednot-model, eigen voorbeeldakte, … */
  bron?: string;
  versie: string;
  datum: string;
  /** Taal van de clausule; ontbreekt = "nl". */
  taal?: Taal;
  /** Id van het anderstalige onderdeel waarvan dit een vertaling is. */
  vertalingVanId?: string;
  /** Wettelijke basis, bv. "art. 3.94 BW", "art. 2.9.4.2.11 VCF". */
  wetsbasis?: string[];
  /** Juridisch nazicht tegenover de huidige wetgeving; ontbreekt = nog niet beoordeeld. */
  nazicht?: Nazicht;
  /** True voor onderdelen die de gebruiker zelf toevoegde (IndexedDB). */
  isGebruiker?: boolean;
  /**
   * Id's van onderdelen die inhoudelijk parallel lopen met dit onderdeel
   * (zelfde onderwerp in een ander aktetype/model: compromis ↔ akte ↔
   * schenking …). Symmetrisch bedoeld — A vermeldt B ⇒ B vermeldt A; de test
   * `parallelle-clausules.test.ts` bewaakt dat. Wijzigt één parallel, dan
   * moeten de andere mee (of de divergentie wordt bewust bevestigd). Zie het
   * parallelclausule-mechanisme (parallelle-clausules.ts, backlog punt 13).
   */
  parallelMetIds?: string[];
  /**
   * Vingerafdruk van elke parallel-partner (`berekenParallelVingerafdruk`) zoals
   * die was toen dit onderdeel er laatst inhoudelijk tegen werd nagekeken. Wijkt
   * de actuele vingerafdruk van de partner af, dan is de parallel gedivergeerd
   * sinds dat nazicht → de divergentietest slaat aan (knipperlicht). Na het mee
   * aanpassen — of het bewust bevestigen — van de parallel wordt deze waarde
   * ververst. Sleutel = partner-id, waarde = hex-vingerafdruk.
   */
  parallelVingerafdrukken?: Record<string, string>;
  /**
   * True: geen eigen genummerde clausulekop ("## N. …") bij het genereren —
   * de tekst sluit aan op het voorgaande onderdeel in de structuur (waarvan
   * het nummer ook voor de subkoppen (### / ####) van dit onderdeel geldt),
   * en de nummering van volgende onderdelen schuift niet op.
   */
  geenEigenNummer?: boolean;
}

/** Prioriteit van een wijzigingsvoorstel, gebruikt om het tabblad "Te valideren" te sorteren. */
export type VoorstelPrioriteit = "hoog" | "midden" | "laag";

export const voorstelPrioriteitLabels: Record<VoorstelPrioriteit, string> = {
  hoog: "Hoog",
  midden: "Midden",
  laag: "Laag",
};

/** Status van een wijzigingsvoorstel. Beslist voorstellen worden uit de wachtrij verwijderd. */
export type VoorstelStatus = "open" | "goedgekeurd" | "afgewezen";

/**
 * Voorstel tot toevoeging of wijziging van een modelonderdeel, ingediend ter
 * validatie door de notaris. Bevat de volledige voorgestelde versie van het
 * onderdeel, zodat goedkeuren neerkomt op het overnemen ervan in de
 * bibliotheek.
 */
export interface Wijzigingsvoorstel {
  id: string;
  /** Id van het bestaande onderdeel waarop dit voorstel een wijziging is; leeg bij een nieuw onderdeel. */
  onderdeelId?: string;
  titel: string;
  /** Toelichting: wat verandert er en waarom. */
  omschrijving: string;
  prioriteit: VoorstelPrioriteit;
  voorgesteldOnderdeel: Modelonderdeel;
  status: VoorstelStatus;
  bron?: string;
  datum: string;
}


/** Eén positie in de structuur van een modeldocument. */
export interface StructuurItem {
  onderdeelId: string;
  verplicht: boolean;
  /** Wanneer dit onderdeel op te nemen is, bv. "enkel bij appartement". */
  conditie?: string;
  /**
   * Naam van de sectiegroep (hoofdkop) waartoe dit onderdeel behoort, bv.
   * "Hoofdelementen van de verkoop". Onderdelen met dezelfde groep worden onder
   * één gedeelde kop (Word-stijl "Kop 1") gebundeld; bij het genereren wordt de
   * kop één keer getoond zodra de groep wijzigt. Ontbreekt = geen groepskop.
   */
  groep?: string;
  /**
   * True voor onderdelen die per partij hernomen worden (bv. de identificatie
   * van elke natuurlijke persoon). Bij het genereren wordt het onderdeel dan
   * één keer per aangeleverde partij-herhaling weergegeven, met de per partij
   * gekende parameterwaarden al ingevuld.
   */
  herhaalPerPartij?: boolean;
  /**
   * True voor onderdelen die per onroerend goed hernomen worden (de verplichte
   * beschrijvingsclausule en de oorsprong van eigendom): een akte kan meerdere
   * goederen en/of meerdere eigendomstitels omvatten. Bij het genereren wordt
   * het onderdeel dan één keer per aangeleverd goed weergegeven, met de per
   * goed gekende waarden (kadastrale gegevens, titel) al ingevuld — zelfde
   * mechanisme als herhaalPerPartij, met een eigen herhalingenlijst.
   */
  herhaalPerGoed?: boolean;
  /**
   * Beperkt de hypothese-varianten die op DEZE structuurpositie zichtbaar
   * zijn tot die waarvan het id met deze prefix begint. Bestaat voor
   * onderdelen die bewust tweemaal in een structuur staan met elk een eigen
   * deelrol — hét voorbeeld is `identiteit-partijen`: de eerste (per partij
   * herhaalde) verwijzing toont de partij-hypotheses, de tweede, eenmalige
   * verwijzing enkel de "notaris-identificatie-*"-vaststellingen. Zonder
   * filter verscheen op beide posities de volledige hypothesecatalogus.
   */
  enkelVariantenMetPrefix?: string;
  /** Spiegelbeeld van `enkelVariantenMetPrefix`: verberg varianten met deze prefix. */
  zonderVariantenMetPrefix?: string;
}

/** Volledig modeldocument, samengesteld uit modelonderdelen. */
export interface Modeldocument {
  id: string;
  titel: string;
  /** Korte titel voor o.a. de bestandsnaam (bv. "Compromis"); ontbreekt = `titel`. */
  korteTitel?: string;
  akteType: string;
  /** Hoofdthema (kantoormap); bepaalt in welk seed-bestand het model staat. */
  thema?: Hoofdthema;
  /** Soort volgens de kantoorconventies (MOD, VB, …); ontbreekt = "MOD". */
  soort?: DocumentSoort;
  omschrijving: string;
  inleiding?: string;
  structuur: StructuurItem[];
  slot?: string;
  bron?: string;
  versie: string;
  datum: string;
  /** Taal van het model; ontbreekt = "nl". */
  taal?: Taal;
  /** Id van het anderstalige model waarvan dit een vertaling is. */
  vertalingVanId?: string;
  /**
   * Authentieke (notariële) akte i.p.v. een onderhands document. Bepaalt de
   * witruimte van het gegenereerde document: bij een authentieke akte komen er
   * GEEN lege regels tussen de alinea's (notariële conventie); bij een onderhands
   * document (bv. een compromis) blijft één lege regel tussen titel en alinea.
   * Ontbreekt = onderhands (één lege regel).
   */
  authentiekeAkte?: boolean;
  isGebruiker?: boolean;
}

/**
 * Voorstel tot toevoeging of wijziging van een volledig modeldocument,
 * ingediend ter validatie door de notaris (bv. via de MCP-server). Bevat het
 * volledige voorgestelde model én de nieuwe modelonderdelen waarnaar de
 * structuur verwijst en die nog niet in de bibliotheek bestaan, zodat
 * goedkeuren neerkomt op het overnemen van model + onderdelen in één keer.
 */
export interface ModeldocumentVoorstel {
  id: string;
  /** Id van het bestaande model waarop dit een wijziging is; leeg = nieuw model. */
  modelId?: string;
  titel: string;
  /** Toelichting: wat verandert er en waarom. */
  omschrijving: string;
  prioriteit: VoorstelPrioriteit;
  voorgesteldModel: Modeldocument;
  /** Nieuwe onderdelen die dit model nodig heeft en nog niet in de bibliotheek zitten. */
  nieuweOnderdelen: Modelonderdeel[];
  status: VoorstelStatus;
  bron?: string;
  datum: string;
}

/**
 * Eén regel in het register van reeds verwerkte bronbestanden (voorbeeldakten,
 * Fednot-modellen, …) die als basis dienden voor modelonderdelen in de
 * bibliotheek. Dit is administratieve metadata over de herkomst — geen
 * modelclausule-inhoud — en valt dus buiten het wijzigingsvoorstel-regime van
 * AGENTS.md: rechtstreeks beheren (toevoegen/bewerken/verwijderen) is hier
 * toegestaan.
 */
export interface BronDocument {
  id: string;
  bestandsnaam: string;
  /** Datum waarop het bestand verwerkt is (ISO, "YYYY-MM-DD"). */
  datum: string;
  opmerking?: string;
}

/**
 * Versiehistoriek van één eigen modelonderdeel: alle vroegere staten van het
 * onderdeel, oudste eerst, bewaard vóór elke bewerking zodat de notaris een
 * oudere versie kan terugzetten.
 */
export interface OnderdeelHistoriek {
  /** Zelfde id als het modelonderdeel waarvan dit de historiek is. */
  id: string;
  versies: Modelonderdeel[];
}
