// ── Goederen & oorsprong van eigendom: bouwer voor de generatie ──────────────
// Pure functies die gestructureerde goed- en titelgegevens omzetten naar de
// goed-herhalingen van genereerDocument: één herhaling per onroerend goed,
// die zowel de verplichte beschrijvingsclausule (beschrijving-onroerend-goed)
// als de oorsprong van eigendom (oorsprong-eigendom) per goed invult. De
// oorsprong wordt SAMENGESTELD uit de bouwstenen van de clausule zelf
// (oudste titel in de basistekst + één schakel-instantie per tussenliggende
// overgang) — nooit vrije tekst buiten de bibliotheek om. De kadastrale
// vergelijking (titel ↔ recent uittreksel ↔ plan) levert per goed de
// nazichtpunten en de afgeleide oppervlaktevermelding.

import type { Herhaling } from "@/data/modeldocumenten";
import {
  oppervlakteRecentVermelding,
  vergelijkPlanMetRecent,
  vergelijkTitelMetRecent,
  type KadasterVergelijking,
} from "./kadaster";

/** Clausule-id waarop de oorsprong-herhalingen mikken (FR-spiegel matcht via vertalingVanId). */
export const OORSPRONG_ONDERDEEL_ID = "oorsprong-eigendom";

/** Soorten tussenliggende overgangen in de oorsprong van eigendom. */
export type TitelSchakelSoort = "verkoop" | "nalatenschap" | "schenking";

export const titelSchakelLabels: Record<TitelSchakelSoort, string> = {
  verkoop: "Tussenliggende verkoop",
  nalatenschap: "Overgang ingevolge overlijden",
  schenking: "Verkrijging bij schenking",
};

/** Bouwsteen-variant per schakelsoort, zoals gedefinieerd in de oorsprong-clausule. */
const SCHAKEL_VARIANT: Record<TitelSchakelSoort, string> = {
  verkoop: "tussenschakel-verkoop",
  nalatenschap: "tussenschakel-nalatenschap",
  schenking: "tussenschakel-schenking",
};

/**
 * In te vullen velden per schakelsoort — parameternamen exact zoals in de
 * bouwsteen-varianten van de oorsprong-clausule, zodat de UI de velden
 * dynamisch kan tonen en de waarden 1-op-1 doorstromen.
 */
export const SCHAKEL_VELDEN: Record<TitelSchakelSoort, { naam: string; label: string }[]> = {
  verkoop: [
    { naam: "naam_verkoper_schakel", label: "Verkoper" },
    { naam: "naam_koper_schakel", label: "Koper" },
    { naam: "notaris_schakel", label: "Notaris" },
    { naam: "plaats_schakel", label: "Standplaats notaris" },
    { naam: "datum_schakel", label: "Datum akte" },
    { naam: "referte_schakel", label: "Overschrijvingsreferte" },
  ],
  nalatenschap: [
    { naam: "naam_overledene", label: "Overledene" },
    { naam: "plaats_overlijden", label: "Plaats overlijden" },
    { naam: "datum_overlijden", label: "Datum overlijden" },
    { naam: "naam_langstlevende", label: "Langstlevende echtgeno(o)t(e)" },
    { naam: "namen_kinderen", label: "Kinderen (namen)" },
    { naam: "notaris_huwelijkscontract", label: "Notaris huwelijkscontract (indien toebedeling)" },
    { naam: "plaats_huwelijkscontract", label: "Standplaats notaris huwelijkscontract" },
    { naam: "datum_huwelijkscontract", label: "Datum huwelijkscontract" },
  ],
  schenking: [
    { naam: "naam_schenker", label: "Schenker" },
    { naam: "naam_begiftigde", label: "Begiftigde" },
    { naam: "notaris_schenking", label: "Notaris" },
    { naam: "plaats_schenking", label: "Standplaats notaris" },
    { naam: "datum_schenking", label: "Datum schenkingsakte" },
  ],
};

/** Eén tussenliggende overgang in de eigendomshistoriek van een goed. */
export interface TitelSchakel {
  soort: TitelSchakelSoort;
  /** Waarden voor de velden van deze schakel (zie SCHAKEL_VELDEN). */
  waarden: Record<string, string>;
}

/** De oudste (dertigjarige) titel — de basistekst van de oorsprong-clausule. */
export interface OudsteTitel {
  oorspronkelijkeEigenaar?: string;
  rechtsvoorganger?: string;
  notaris?: string;
  plaats?: string;
  datum?: string;
  overschrijvingsreferte?: string;
}

/** Eén onroerend goed in de akte, met zijn kadastrale bronnen en titelhistoriek. */
export interface GoedMetTitel {
  /** Kop boven het blok in het document, bv. "Goed 1 — woning Kerkstraat 12". */
  label?: string;
  /** Type-hypothese van de beschrijvingsclausule ("huis", "grond", "appartement-mede-eigendom", …). */
  typeVariantId?: string;
  // ── Beschrijving ──
  gemeente?: string;
  deelgemeente?: string;
  afdeling?: string;
  adres?: string;
  inleidendeOmschrijving?: string;
  // ── Kadastrale aanduiding volgens de eigendomstitel ──
  sectieTitel?: string;
  perceelnummerTitel?: string;
  oppervlakteTitel?: string;
  // ── Kadastrale aanduiding volgens recent uittreksel ──
  sectieRecent?: string;
  perceelnummerRecent?: string;
  oppervlakteRecent?: string;
  // ── Opmetingsplan (optioneel) ──
  planPerceelnummer?: string;
  planOppervlakte?: string;
  planReferte?: string;
  // ── Titelhistoriek ──
  oudsteTitel?: OudsteTitel;
  schakels?: TitelSchakel[];
}

/** Kadastrale vergelijking van één goed: titel ↔ recent, en (indien plan) plan ↔ recent. */
export interface GoedVergelijking {
  titelVsRecent: KadasterVergelijking;
  planVsRecent?: KadasterVergelijking;
  /** Alle meldingen samen, klaar voor weergave/nazicht. */
  meldingen: string[];
}

/** Vergelijkt de kadastrale bronnen van één goed (historische nummers, oppervlaktes, plan). */
export function vergelijkGoed(goed: GoedMetTitel): GoedVergelijking {
  const titelVsRecent = vergelijkTitelMetRecent(
    { sectie: goed.sectieTitel, perceelnummer: goed.perceelnummerTitel, oppervlakte: goed.oppervlakteTitel },
    { sectie: goed.sectieRecent, perceelnummer: goed.perceelnummerRecent, oppervlakte: goed.oppervlakteRecent }
  );
  const heeftPlan = !!(goed.planPerceelnummer || goed.planOppervlakte);
  const planVsRecent = heeftPlan
    ? vergelijkPlanMetRecent(
        { sectie: goed.sectieRecent, perceelnummer: goed.planPerceelnummer, oppervlakte: goed.planOppervlakte },
        { sectie: goed.sectieRecent, perceelnummer: goed.perceelnummerRecent, oppervlakte: goed.oppervlakteRecent }
      )
    : undefined;
  return {
    titelVsRecent,
    planVsRecent,
    meldingen: [...titelVsRecent.meldingen, ...(planVsRecent?.meldingen ?? [])],
  };
}

const zetIndien = (waarden: Record<string, string>, naam: string, waarde?: string): void => {
  if (waarde?.trim()) waarden[naam] = waarde.trim();
};

/**
 * Bouwt de goed-herhaling van één goed: de beschrijvings- en oudste-titel-
 * waarden, de afgeleide oppervlaktevermelding, de type-hypothese en de
 * oorsprong-schakels (gericht op de oorsprong-clausule, FR-spiegel inbegrepen
 * via vertalingVanId-matching in de engine).
 */
export function bouwGoedHerhaling(goed: GoedMetTitel): Herhaling {
  const waarden: Record<string, string> = {};
  // Beschrijving
  zetIndien(waarden, "gemeente", goed.gemeente);
  zetIndien(waarden, "deelgemeente", goed.deelgemeente);
  zetIndien(waarden, "afdeling_omschrijving", goed.afdeling);
  zetIndien(waarden, "adres_onroerend_goed", goed.adres);
  zetIndien(waarden, "inleidende_omschrijving_gebouw_of_perceel", goed.inleidendeOmschrijving);
  zetIndien(waarden, "sectie_titel", goed.sectieTitel);
  zetIndien(waarden, "perceelnummer_titel", goed.perceelnummerTitel);
  zetIndien(waarden, "oppervlakte_titel", goed.oppervlakteTitel);
  zetIndien(waarden, "sectie_recent_kadaster", goed.sectieRecent);
  zetIndien(waarden, "perceelnummer_recent_kadaster", goed.perceelnummerRecent);
  zetIndien(waarden, "oppervlakte_recent_kadaster", goed.oppervlakteRecent);
  zetIndien(
    waarden,
    "oppervlakte_recent_kadaster_vermelding",
    oppervlakteRecentVermelding(goed.oppervlakteTitel, goed.oppervlakteRecent)
  );
  // Plan (beschrijving-op-plan-hypothese en verwante clausules)
  zetIndien(waarden, "referte_plan_opname_databank_met_twee_maal_vijf_cijfers", goed.planReferte);
  // Oudste titel (basistekst oorsprong-clausule)
  zetIndien(waarden, "naam_oorspronkelijke_eigenaar", goed.oudsteTitel?.oorspronkelijkeEigenaar);
  zetIndien(waarden, "naam_rechtsvoorganger", goed.oudsteTitel?.rechtsvoorganger);
  zetIndien(waarden, "notaris_titel", goed.oudsteTitel?.notaris);
  zetIndien(waarden, "plaats_titel", goed.oudsteTitel?.plaats);
  zetIndien(waarden, "datum_titel", goed.oudsteTitel?.datum);
  zetIndien(waarden, "overschrijvingsreferte", goed.oudsteTitel?.overschrijvingsreferte);

  const schakels = (goed.schakels ?? []).map((schakel) => ({
    onderdeelId: OORSPRONG_ONDERDEEL_ID,
    variantId: SCHAKEL_VARIANT[schakel.soort],
    waarden: schakel.waarden,
  }));

  return {
    label: goed.label?.trim() || undefined,
    waarden,
    variantId: goed.typeVariantId,
    schakels: schakels.length > 0 ? schakels : undefined,
  };
}

/** Bouwt de volledige goed-herhalingenlijst voor genereerDocument. */
export function bouwGoedHerhalingen(goederen: readonly GoedMetTitel[]): Herhaling[] {
  return goederen.map((goed, i) => {
    const herhaling = bouwGoedHerhaling(goed);
    return { ...herhaling, label: herhaling.label ?? (goederen.length > 1 ? `Goed ${i + 1}` : undefined) };
  });
}
