import {
  berekenSchenking,
  relatieKort,
  type Relatie,
  type SchijfDetail as BelastingSchijf,
  type WetRef,
} from "@/data/belastingen";
import type { Gewest } from "@/lib/context/gewest";

export type AkteType =
  | "verkoop"
  | "hypotheek"
  | "schenking-onroerend"
  | "schenking-roerend"
  | "verdeling";

// Eén bron van waarheid: gewest en verwantschap komen uit de belastingmodule.
export type GewestEreloon = Gewest;
export type { Relatie };

export type SchenkingsWijze = "voorschot" | "buiten_deel";

export const schenkingsWijzeLabels: Record<SchenkingsWijze, string> = {
  voorschot: "Als voorschot op erfenis (inbrengplichtig)",
  buiten_deel: "Buiten deel (vrijgesteld van inbreng)",
};

export interface AkteMeta {
  label: string;
  icoon: string;
  grondslachLabel: string;
  heeftEigenWoning: boolean;
  heeftRelatie: boolean;
  heeftSchenkingsWijze: boolean;
  wetRefs?: WetRef[];
}

export const akteMeta: Record<AkteType, AkteMeta> = {
  verkoop: {
    label: "Verkoop onroerend goed",
    icoon: "🏠",
    grondslachLabel: "Koopsom",
    heeftEigenWoning: true,
    heeftRelatie: false,
    heeftSchenkingsWijze: false,
    wetRefs: [
      { wetId: "tariefbesluit", artikelId: "kb1950-barema-J", label: "KB 1950 Schaal J/Jbis — Honorarium verkoop" },
      { wetId: "wet-hypothecair-krediet", artikelId: "whk-6", label: "WHK art. 6 — Verplichte vermeldingen hypotheekakte" },
    ],
  },
  hypotheek: {
    label: "Hypothecaire lening",
    icoon: "🏦",
    grondslachLabel: "Kredietbedrag",
    heeftEigenWoning: true,
    heeftRelatie: false,
    heeftSchenkingsWijze: false,
    wetRefs: [
      { wetId: "tariefbesluit", artikelId: "kb1950-barema-G", label: "KB 1950 Schaal G/Gbis — Honorarium financiering" },
      { wetId: "hypotheekwet", artikelId: "hw-75", label: "HW art. 75 — Inschrijving hypotheek" },
      { wetId: "tariefbesluit", artikelId: "kb1950-retributies", label: "KB 14.09.2016 — Retributies hypotheek" },
    ],
  },
  "schenking-onroerend": {
    label: "Schenking onroerend",
    icoon: "🏡",
    grondslachLabel: "Waarde goed",
    heeftEigenWoning: false,
    heeftRelatie: true,
    heeftSchenkingsWijze: true,
    wetRefs: [
      { wetId: "tariefbesluit", artikelId: "kb1950-barema-H-F", label: "KB 1950 Schalen F/H — Honorarium schenking" },
      { wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-8-6-1-1", label: "VCF art. 2.8.6.1.1 — Aangifte schenking onroerend" },
    ],
  },
  "schenking-roerend": {
    label: "Schenking roerend",
    icoon: "💶",
    grondslachLabel: "Geschonken bedrag",
    heeftEigenWoning: false,
    heeftRelatie: true,
    heeftSchenkingsWijze: true,
    wetRefs: [
      { wetId: "tariefbesluit", artikelId: "kb1950-barema-H-F", label: "KB 1950 Schalen F/H — Honorarium schenking" },
      { wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-8-7-1-1", label: "VCF art. 2.8.7.1.1 — Handgift/bankgift roerend" },
    ],
  },
  verdeling: {
    label: "Verdeling",
    icoon: "⚖️",
    grondslachLabel: "Netto-waarde te verdelen",
    heeftEigenWoning: false,
    heeftRelatie: false,
    heeftSchenkingsWijze: false,
    wetRefs: [
      { wetId: "tariefbesluit", artikelId: "kb1950-barema-H-F", label: "KB 1950 Schaal H — Honorarium verdeling" },
      { wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-10-1-0-1", label: "VCF art. 2.10.1.0.1 — Verdeelrecht 2,5%" },
    ],
  },
};

// ── Getarifeerde notariële honoraria ─────────────────────────────────────────
// Tarief van de honoraria der notarissen in bijlage van het KB van 16 december
// 1950, geconsolideerd na het KB van 22 november 2022 (in voege sinds 1.1.2023).
//
// De variabele percentages liggen vast in de wet. Het VAST GEDEELTE van de
// schalen G/J/K(bis) en de forfaitaire kosten worden tweejaarlijks geïndexeerd
// (art. 19). Onderstaande vaste gedeelten zijn geïndexeerd op 01/01/2026
// (cumulatief +14,055 % t.o.v. januari 2022).
export interface BaremaSchijf {
  tot: number | null;
  pct: number;
}

export interface Barema {
  code: string;
  omschrijving: string;
  vastGedeelte: number; // geïndexeerd 01/01/2026
  schijven: BaremaSchijf[];
}

const VG_GJK = 285; // vast gedeelte schalen G / J / K   (basis 2022: € 250)
const VG_BIS = 257; // vast gedeelte schalen Jbis / Kbis  (basis 2022: € 225)

export const BAREMA: Record<string, Barema> = {
  // Onroerende akten en hun financiering — grenzen 7.500 / 17.500 / 30.000 /
  // 45.495 / 64.090 / 250.095 / 500.000 EUR.
  J: {
    code: "J",
    omschrijving: "Verkoop onroerend goed (algemeen)",
    vastGedeelte: VG_GJK,
    schijven: [
      { tot: 7_500, pct: 2.5 },
      { tot: 17_500, pct: 2.5 },
      { tot: 30_000, pct: 1.75 },
      { tot: 45_495, pct: 1.71 },
      { tot: 64_090, pct: 1.14 },
      { tot: 250_095, pct: 0.57 },
      { tot: 500_000, pct: 0.2 },
      { tot: null, pct: 0.2 },
    ],
  },
  Jbis: {
    code: "Jbis",
    omschrijving: "Verkoop — enige eigen woning (verlaagd)",
    vastGedeelte: VG_BIS,
    schijven: [
      { tot: 7_500, pct: 2.5 },
      { tot: 17_500, pct: 2.5 },
      { tot: 30_000, pct: 2.0 },
      { tot: 45_495, pct: 1.5 },
      { tot: 64_090, pct: 0.5 },
      { tot: 250_095, pct: 0.485 },
      { tot: 500_000, pct: 0.3 },
      { tot: null, pct: 0.2 },
    ],
  },
  G: {
    code: "G",
    omschrijving: "Financiering / kredietopening (algemeen)",
    vastGedeelte: VG_GJK,
    schijven: [
      { tot: 7_500, pct: 0.75 },
      { tot: 17_500, pct: 0.65 },
      { tot: 30_000, pct: 0.5 },
      { tot: 45_495, pct: 0.4 },
      { tot: 64_090, pct: 0.4 },
      { tot: 250_095, pct: 0.228 },
      { tot: 500_000, pct: 0.046 },
      { tot: null, pct: 0.046 },
    ],
  },
  Gbis: {
    code: "Gbis",
    omschrijving: "Financiering — enige eigen woning (verlaagd)",
    vastGedeelte: 0, // schaal Gbis heeft geen vast gedeelte
    schijven: [
      { tot: 7_500, pct: 1.368 },
      { tot: 17_500, pct: 1.094 },
      { tot: 30_000, pct: 0.73 },
      { tot: 45_495, pct: 0.547 },
      { tot: 64_090, pct: 0.365 },
      { tot: 250_095, pct: 0.182 },
      { tot: 500_000, pct: 0.036 },
      { tot: null, pct: 0.036 },
    ],
  },
  // Diverse akten — grenzen 7.500 / 17.500 / 30.000 / 45.495 / 64.095 /
  // 250.095 EUR. Geen vast gedeelte.
  F: {
    code: "F",
    omschrijving: "Schenking bij voorschot op erfdeel (erfgerechtigden)",
    vastGedeelte: 0,
    schijven: [
      { tot: 7_500, pct: 1.425 },
      { tot: 17_500, pct: 1.14 },
      { tot: 30_000, pct: 0.684 },
      { tot: 45_495, pct: 0.57 },
      { tot: 64_095, pct: 0.456 },
      { tot: 250_095, pct: 0.228 },
      { tot: null, pct: 0.0456 },
    ],
  },
  H: {
    code: "H",
    omschrijving: "Schenking aan niet-erfgerechtigden / verdeling",
    vastGedeelte: 0,
    schijven: [
      { tot: 7_500, pct: 2.85 },
      { tot: 17_500, pct: 1.71 },
      { tot: 30_000, pct: 1.425 },
      { tot: 45_495, pct: 1.14 },
      { tot: 64_095, pct: 0.855 },
      { tot: 250_095, pct: 0.57 },
      { tot: null, pct: 0.057 },
    ],
  },
};

export interface SchijfDetail {
  label: string;
  percentage: number;
  grondslag: number;
  bedrag: number;
}

export interface HonorariumResultaat {
  baremaCode: string;
  baremaOmschrijving: string;
  vastGedeelte: number;
  detail: SchijfDetail[]; // variabele schijven (zonder vast gedeelte)
  honorarium: number; // vast gedeelte + variabel gedeelte
}

// Bepaalt de toepasselijke schaal volgens het tariefbesluit:
//  · verkoop          → J  (art. 81) / Jbis bij enige eigen woning
//  · financiering     → G  (art. 53) / Gbis bij enige eigen woning
//  · verdeling        → H  (art. 54)
//  · schenking        → F  bij voorschot op erfenis (inbrengplichtig, art. 39 §3),
//                        H  bij schenking buiten deel (vrijgesteld van inbreng, art. 39 §2)
export function kiesBarema(
  akteType: AkteType,
  opties: { eigenWoning?: boolean; schenkingsWijze?: SchenkingsWijze } = {}
): string {
  const { eigenWoning = false, schenkingsWijze = "buiten_deel" } = opties;
  switch (akteType) {
    case "verkoop":
      return eigenWoning ? "Jbis" : "J";
    case "hypotheek":
      return eigenWoning ? "Gbis" : "G";
    case "verdeling":
      return "H";
    case "schenking-onroerend":
    case "schenking-roerend":
      return schenkingsWijze === "voorschot" ? "F" : "H";
  }
}

export function berekenHonorarium(
  bedrag: number,
  baremaCode: string
): HonorariumResultaat {
  const b = BAREMA[baremaCode];
  const detail: SchijfDetail[] = [];
  let ondergrens = 0;
  let variabel = 0;
  for (const s of b.schijven) {
    if (bedrag <= ondergrens) break;
    const bovengrens = Math.min(bedrag, s.tot ?? Infinity);
    const grondslag = bovengrens - ondergrens;
    const bedragSchijf = grondslag * (s.pct / 100);
    variabel += bedragSchijf;
    detail.push({
      label:
        s.tot === null
          ? `> €${ondergrens.toLocaleString("nl-BE")}`
          : `€${ondergrens.toLocaleString("nl-BE")} – €${s.tot.toLocaleString(
              "nl-BE"
            )}`,
      percentage: s.pct,
      grondslag,
      bedrag: bedragSchijf,
    });
    ondergrens = s.tot ?? ondergrens;
  }
  return {
    baremaCode: b.code,
    baremaOmschrijving: b.omschrijving,
    vastGedeelte: b.vastGedeelte,
    detail,
    honorarium: b.vastGedeelte + variabel,
  };
}

// Zet belasting-schijven (van/tot/tarief) om naar het ereloon-detailformaat.
function mapSchijven(detail: BelastingSchijf[]): SchijfDetail[] {
  return detail.map((d) => ({
    label: `€${Math.round(d.van).toLocaleString("nl-BE")} – €${Math.round(
      d.tot
    ).toLocaleString("nl-BE")}`,
    percentage: d.tarief,
    grondslag: d.tot - d.van,
    bedrag: d.bedrag,
  }));
}

// ── Wettelijk getarifeerde administratieve kosten (vacaties) ─────────────────
// Tariefbesluit art. 2 §2: het gezamenlijk bedrag van de administratieve kosten
// en de niet-individualiseerbare uitgaven is forfaitair vastgesteld. Bedragen
// geïndexeerd op 01/01/2026 (zonder btw):
//   · eerste/hoofdakte (verkoop, (her)financiering, basis-/verkavelingsakte): € 855
//   · verbonden of accessoire akte vanaf de tweede                          : € 627
//   · oprichting BV met standaardstatuten                                   : € 314
export const AKTEKOSTEN_2026 = {
  hoofdakte: 855, // basis 2022: € 750
  verbondenAkte: 627, // basis 2022: € 550
  bvStandaard: 314, // basis 2022: € 275
} as const;

export interface AktekostResultaat {
  label: string;
  bedrag: number; // zonder btw
  opmerking: string;
}

export function getAktekosten(
  akteType: AkteType,
  verbonden: boolean
): AktekostResultaat {
  const inScope =
    akteType === "verkoop" ||
    akteType === "hypotheek" ||
    akteType === "schenking-onroerend" ||
    akteType === "verdeling";
  const bedrag = verbonden
    ? AKTEKOSTEN_2026.verbondenAkte
    : AKTEKOSTEN_2026.hoofdakte;
  return {
    label: verbonden
      ? "Forfaitaire administratieve kosten — verbonden akte"
      : "Forfaitaire administratieve kosten — eerste akte",
    bedrag,
    opmerking: inScope
      ? "Wettelijk forfait (tariefbesluit art. 2 §2), geïndexeerd 01/01/2026 — excl. btw."
      : "Indicatief forfait — art. 2 §2 geldt strikt voor verkoop, financiering en basis-/verkavelingsakten.",
  };
}

// ── Hypothecaire retributies (kantoor Rechtszekerheid) ───────────────────────
// KB van 14 september 2016, laatst gewijzigd bij KB van 18 mei 2022. Forfaitaire
// retributies, niet onderworpen aan btw.
export const HYP_RETRIBUTIES = {
  overschrijving: 285,
  inschrijvingTot300k: 270, // hoofdsom + bijhorigheden ≤ 300.000 EUR
  inschrijvingBoven300k: 1160, // hoofdsom + bijhorigheden > 300.000 EUR
  doorhaling: 350,
  hypothecaireOpzoeking: 180, // oorspronkelijk dringend getuigschrift
  afschriftAkte: 65,
} as const;

export interface RetributieResultaat {
  label: string;
  bedrag: number;
  opmerking?: string;
}

export function getRetributies(
  akteType: AkteType,
  bedrag: number
): RetributieResultaat[] {
  switch (akteType) {
    case "verkoop":
    case "schenking-onroerend":
    case "verdeling":
      return [
        {
          label: "Overschrijving van de akte",
          bedrag: HYP_RETRIBUTIES.overschrijving,
          opmerking: "Forfait kantoor Rechtszekerheid (KB 14.09.2016).",
        },
        {
          label: "Hypothecaire opzoeking / getuigschrift",
          bedrag: HYP_RETRIBUTIES.hypothecaireOpzoeking,
          opmerking: "Oorspronkelijk getuigschrift, dringend binnen 8 werkdagen.",
        },
      ];
    case "hypotheek": {
      // Inschrijving op hoofdsom + bijhorigheden (≈ krediet × 110 %).
      const verzekerdBedrag = bedrag * 1.1;
      const inschrijving =
        verzekerdBedrag > 300_000
          ? HYP_RETRIBUTIES.inschrijvingBoven300k
          : HYP_RETRIBUTIES.inschrijvingTot300k;
      return [
        {
          label: "Inschrijving van de hypotheek",
          bedrag: inschrijving,
          opmerking: `Op hoofdsom + bijhorigheden ≈ € ${Math.round(
            verzekerdBedrag
          ).toLocaleString("nl-BE")} → ${
            verzekerdBedrag > 300_000 ? "> 300.000 EUR" : "≤ 300.000 EUR"
          } (KB 14.09.2016).`,
        },
      ];
    }
    case "schenking-roerend":
      return [];
  }
}

// ── Overheidsrechten (registratie- en hypotheekrechten) ──────────────────────
export interface HeffingResultaat {
  label: string;
  percentage: number | null;
  bedrag: number;
  opmerking?: string;
  isIndicatief?: boolean;
  details?: SchijfDetail[];
}

export function berekenHeffing(
  akteType: AkteType,
  bedrag: number,
  gewest: GewestEreloon,
  opties: { eigenWoning?: boolean; relatie?: Relatie } = {}
): HeffingResultaat | null {
  const { eigenWoning = false, relatie = "rechte_lijn_partner" } = opties;

  switch (akteType) {
    case "verkoop": {
      if (gewest === "Vlaanderen") {
        if (eigenWoning) {
          return {
            label: "Verkooprecht — enige eigen woning (VCF art. 2.9.4.0.1)",
            percentage: 3,
            bedrag: bedrag * 0.03,
            opmerking: "Enige eigen woning · koopsom ≤ €500.000 · hoofdverblijf binnen 3 jaar",
          };
        }
        return {
          label: "Verkooprecht — algemeen tarief (VCF art. 2.9.1.0.1)",
          percentage: 12,
          bedrag: bedrag * 0.12,
        };
      }
      if (gewest === "Wallonië") {
        return {
          label: "Droit d'enregistrement — algemeen tarief",
          percentage: 12.5,
          bedrag: bedrag * 0.125,
          isIndicatief: true,
          opmerking: "Verminderd tarief (6%) mogelijk voor eerste aankoop eigen woning — raadpleeg actuele voorwaarden",
        };
      }
      // Brussel
      if (eigenWoning) {
        const grondslag = Math.max(0, bedrag - 200_000);
        const besparing = (bedrag - grondslag) * 0.125;
        return {
          label: "Droit d'enregistrement — abattement €200.000 voor eigen woning",
          percentage: 12.5,
          bedrag: grondslag * 0.125,
          isIndicatief: true,
          opmerking: `Heffingsbasis na abattement: €${grondslag.toLocaleString("nl-BE")} — besparing vs. algemeen tarief: €${Math.round(besparing).toLocaleString("nl-BE")}`,
        };
      }
      return {
        label: "Droit d'enregistrement — algemeen tarief",
        percentage: 12.5,
        bedrag: bedrag * 0.125,
        isIndicatief: true,
      };
    }

    case "hypotheek": {
      const verzekerdBedrag = bedrag * 1.1;
      return {
        label: "Hypotheekrecht 0,3% op verzekerd bedrag (VCF art. 2.11.1.0.1)",
        percentage: 0.3,
        bedrag: verzekerdBedrag * 0.003,
        isIndicatief: gewest !== "Vlaanderen",
        opmerking: `Verzekerd bedrag ≈ krediet × 110% = €${Math.round(verzekerdBedrag).toLocaleString("nl-BE")} (hoofd + 3j rente + kosten)`,
      };
    }

    case "schenking-roerend": {
      // Hergebruikt de belastingmodule (consistente tarieven over de 3 gewesten).
      const r = berekenSchenking(gewest, "roerend", relatie, bedrag);
      return {
        label: `Schenkbelasting roerend — ${relatieKort[relatie]} (${r.effectiefTarief}%)`,
        percentage: r.effectiefTarief,
        bedrag: r.totaal,
        opmerking:
          gewest === "Vlaanderen"
            ? "VCF art. 2.8.4.1.1 — vast tarief 3% (rechte lijn/partner) of 7% (anderen)."
            : "Vast tarief volgens het gewest.",
      };
    }

    case "schenking-onroerend": {
      // Geharmoniseerd progressief barema (identiek in de 3 gewesten).
      const r = berekenSchenking(gewest, "onroerend", relatie, bedrag);
      return {
        label: `Schenkbelasting onroerend — ${relatieKort[relatie]}`,
        percentage: null,
        bedrag: r.totaal,
        details: mapSchijven(r.detail),
        opmerking:
          "Geharmoniseerd barema, identiek in de drie gewesten: 3/9/18/27% (rechte lijn) · 10/20/30/40% (anderen).",
      };
    }

    case "verdeling": {
      if (gewest === "Vlaanderen") {
        return {
          label: "Verdeelrecht 2,5% (VCF art. 2.10.1.0.1)",
          percentage: 2.5,
          bedrag: bedrag * 0.025,
          opmerking: "Verdeling gezinswoning na echtscheiding: verlaagd tarief 1% (VCF art. 2.10.1.0.2)",
        };
      }
      return {
        label: "Verdeelrecht — indicatief",
        percentage: 1,
        bedrag: bedrag * 0.01,
        isIndicatief: true,
        opmerking: "Indicatief — raadpleeg de actuele tarieven van het gewest",
      };
    }
  }
}

export function getHeffingWetRefs(
  akteType: AkteType,
  gewest: Gewest,
  eigenWoning: boolean
): WetRef[] {
  if (akteType === "verkoop") {
    if (gewest === "Vlaanderen") {
      const refs: WetRef[] = [{ wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-9-1-0-1", label: "VCF art. 2.9.1.0.1 — Verkooprecht 12%/3%" }];
      if (eigenWoning) refs.push({ wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-9-4-0-1", label: "VCF art. 2.9.4.0.1 — Meeneembaarheid verkooprecht" });
      return refs;
    }
    if (gewest === "Brussel") return [{ wetId: "code-droits-succession-bxl", artikelId: "cds-bxl-art-5", label: "CDS-BXL — Registratierechten Brussel 12,5%/3,5%" }];
    if (gewest === "Wallonië") return [{ wetId: "cwf-erfbelasting", artikelId: "cwf-art-d-xi-1", label: "CWF art. D.XI.1 — Registratierechten Wallonië 12,5%/6%" }];
  }
  if (akteType === "hypotheek") {
    if (gewest === "Vlaanderen") return [{ wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-11-1-0-1", label: "VCF art. 2.11.1.0.1 — Hypotheekrecht 0,3%" }];
  }
  if (akteType === "schenking-onroerend") {
    if (gewest === "Vlaanderen") return [{ wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-8-4-1-2", label: "VCF art. 2.8.4.1.2 — Schenkbelasting onroerend" }];
    if (gewest === "Brussel") return [{ wetId: "code-droits-succession-bxl", artikelId: "cds-bxl-art-5", label: "CDS-BXL — Schenkingsrechten Brussel" }];
    if (gewest === "Wallonië") return [{ wetId: "cwf-erfbelasting", artikelId: "cwf-art-d-xi-2", label: "CWF art. D.XI.2 — Schenkingsrechten Wallonië" }];
  }
  if (akteType === "schenking-roerend") {
    if (gewest === "Vlaanderen") return [{ wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-8-4-1-1", label: "VCF art. 2.8.4.1.1 — Schenkbelasting roerend 3%/7%" }];
    if (gewest === "Brussel") return [{ wetId: "code-droits-succession-bxl", artikelId: "cds-bxl-art-5", label: "CDS-BXL — Schenkingsrechten Brussel" }];
    if (gewest === "Wallonië") return [{ wetId: "cwf-erfbelasting", artikelId: "cwf-art-d-xi-2", label: "CWF art. D.XI.2 — Schenkingsrechten Wallonië" }];
  }
  if (akteType === "verdeling") {
    if (gewest === "Vlaanderen") return [{ wetId: "vlaamse-codex-belastingen", artikelId: "vcf-2-10-1-0-1", label: "VCF art. 2.10.1.0.1 — Verdeelrecht 2,5%" }];
  }
  return [];
}
