import { describe, it, expect } from "vitest";
import {
  parsePerceelnummer,
  parseOppervlakteM2,
  vergelijkTitelMetRecent,
  vergelijkPlanMetRecent,
  oppervlakteRecentVermelding,
} from "./kadaster";

describe("parsePerceelnummer", () => {
  it("parseert het historische titelformaat", () => {
    expect(parsePerceelnummer("60 F 22")).toEqual({
      grondnummer: 60,
      bisnummer: undefined,
      letterexponent: "F",
      cijferexponent: 22,
    });
    expect(parsePerceelnummer("60/2 F 3")).toEqual({
      grondnummer: 60,
      bisnummer: 2,
      letterexponent: "F",
      cijferexponent: 3,
    });
    expect(parsePerceelnummer("125 B")).toMatchObject({ grondnummer: 125, letterexponent: "B" });
    expect(parsePerceelnummer("319 e")).toMatchObject({ grondnummer: 319, letterexponent: "E" });
  });

  it("parseert het recente uittrekselformaat", () => {
    expect(parsePerceelnummer("0060F22P0000")).toEqual({
      grondnummer: 60,
      bisnummer: undefined,
      letterexponent: "F",
      cijferexponent: 22,
      partitie: "P0000",
    });
    expect(parsePerceelnummer("0060/02F03P0001")).toMatchObject({
      grondnummer: 60,
      bisnummer: 2,
      letterexponent: "F",
      cijferexponent: 3,
    });
  });

  it("weigert onherkenbare invoer in plaats van te gokken", () => {
    expect(parsePerceelnummer("")).toBeNull();
    expect(parsePerceelnummer("perceel achter de kerk")).toBeNull();
  });
});

describe("parseOppervlakteM2", () => {
  it("rekent ha/a/ca om naar m²", () => {
    expect(parseOppervlakteM2("1a 80ca")).toBe(180);
    expect(parseOppervlakteM2("1ha 20a 35ca")).toBe(12_035);
    expect(parseOppervlakteM2("35 ca")).toBe(35);
  });

  it("parseert m²-notaties, ook met Belgische duizendtallen", () => {
    expect(parseOppervlakteM2("180 m²")).toBe(180);
    expect(parseOppervlakteM2("12.035 m²")).toBe(12_035);
    expect(parseOppervlakteM2("1.234,56 m2")).toBe(1234.56);
  });

  it("weigert kale getallen (eenheid onbekend = gokken)", () => {
    expect(parseOppervlakteM2("180")).toBeNull();
  });
});

describe("vergelijkTitelMetRecent", () => {
  it("herkent hetzelfde perceel over de twee formaten heen", () => {
    const v = vergelijkTitelMetRecent(
      { sectie: "F", perceelnummer: "60 F 22", oppervlakte: "1a 80ca" },
      { sectie: "F", perceelnummer: "0060F22P0000", oppervlakte: "180 m²" }
    );
    expect(v.sectie).toBe("zelfde");
    expect(v.perceelnummer).toBe("zelfde");
    expect(v.oppervlakte).toBe("zelfde");
    expect(v.meldingen).toEqual([]);
  });

  it("meldt een afwijkend perceelnummer en oppervlakteverschil", () => {
    const v = vergelijkTitelMetRecent(
      { sectie: "F", perceelnummer: "60 F 22", oppervlakte: "1a 80ca" },
      { sectie: "F", perceelnummer: "0060G22P0000", oppervlakte: "195 m²" }
    );
    expect(v.perceelnummer).toBe("verschillend");
    expect(v.oppervlakte).toBe("verschillend");
    expect(v.oppervlakteVerschilM2).toBe(15);
    expect(v.meldingen).toHaveLength(2);
  });

  it("meldt onvergelijkbaarheid expliciet in plaats van stil te zwijgen", () => {
    const v = vergelijkTitelMetRecent(
      { sectie: "F", perceelnummer: "achterste weide", oppervlakte: "1a 80ca" },
      { sectie: "F", perceelnummer: "0060F22P0000" }
    );
    expect(v.perceelnummer).toBe("onvergelijkbaar");
    expect(v.oppervlakte).toBe("onvergelijkbaar");
    expect(v.meldingen.some((m) => m.includes("manueel nakijken"))).toBe(true);
  });
});

describe("vergelijkPlanMetRecent", () => {
  it("herformuleert de meldingen naar de plan-bron", () => {
    const v = vergelijkPlanMetRecent(
      { sectie: "F", perceelnummer: "60 F 22", oppervlakte: "182 m²" },
      { sectie: "F", perceelnummer: "0060F22P0000", oppervlakte: "180 m²" }
    );
    expect(v.oppervlakte).toBe("verschillend");
    expect(v.meldingen[0]).toContain("plan");
  });
});

describe("oppervlakteRecentVermelding", () => {
  it('geeft "dezelfde oppervlakte" bij exacte overeenkomst na omzetting', () => {
    expect(oppervlakteRecentVermelding("1a 80ca", "180 m²")).toBe("dezelfde oppervlakte");
  });

  it("geeft de voluit-vermelding bij afwijking of onbekende titeloppervlakte", () => {
    expect(oppervlakteRecentVermelding("1a 80ca", "195 m²")).toBe("een oppervlakte van 195 m²");
    expect(oppervlakteRecentVermelding(undefined, "180 m²")).toBe("een oppervlakte van 180 m²");
  });

  it("geeft undefined zonder recente oppervlakte", () => {
    expect(oppervlakteRecentVermelding("1a 80ca", undefined)).toBeUndefined();
  });
});
