import { describe, it, expect } from "vitest";
import { relevanteBriefCategorieen, stelModelmailsSamenAutonoom, mailWaardenVoorOntvanger } from "./modelmails";
import { maakVeld, type Dossier, type Partij } from "./types";
import { seedBrieven } from "@/data/modelbrieven";

function maakDossier(overschrijf: Partial<Dossier> = {}): Dossier {
  const verkoper: Partij = { naam: "Janssens", voornaam: "Marie", rol: "verkoper" };
  const koper: Partij = { naam: "Peeters", voornaam: "Jan", rol: "koper" };
  return {
    id: "d1",
    dossiertype: "verkoop-zonder-krediet",
    status: "compromis-ontvangen",
    partijen: maakVeld([verkoper, koper], "compromis"),
    goed: maakVeld({ adres: "Brusselsesteenweg 100, 3080 Tervuren" }, "kadastraal-uittreksel"),
    prijs: maakVeld(350000, "compromis"),
    ontbrekendeStukken: [],
    tegenstrijdigheden: [],
    aangemaakt: "2026-06-01T00:00:00.000Z",
    aangepast: "2026-06-01T00:00:00.000Z",
    ...overschrijf,
  } as Dossier;
}

describe("mailWaardenVoorOntvanger", () => {
  const waarden = { naam_koper: "Jan Peeters", naam_verkoper: "Marie Janssens", naam: "X" };

  it("vult {{naam}} met de koper bij een koper-cliëntmail", () => {
    expect(mailWaardenVoorOntvanger("koper (cliënt)", waarden).naam).toBe("Jan Peeters");
  });

  it("vult {{naam}} met de verkoper bij een verkoper-cliëntmail", () => {
    expect(mailWaardenVoorOntvanger("verkoper", waarden).naam).toBe("Marie Janssens");
  });

  it("laat {{naam}} ongemoeid voor tussenpersonen (confrater, bank, makelaar)", () => {
    expect(mailWaardenVoorOntvanger("confrater (koper)", waarden).naam).toBe("X");
    expect(mailWaardenVoorOntvanger("notaris verkoper / makelaar", waarden).naam).toBe("X");
    expect(mailWaardenVoorOntvanger("bank", waarden).naam).toBe("X");
  });
});

describe("relevanteBriefCategorieen", () => {
  it("neemt kredietdossier op bij verkoop met krediet", () => {
    expect(relevanteBriefCategorieen("verkoop-met-krediet")).toContain("kredietdossier");
  });

  it("neemt kredietdossier niet op bij verkoop zonder krediet", () => {
    expect(relevanteBriefCategorieen("verkoop-zonder-krediet")).not.toContain("kredietdossier");
  });

  it("kiest vennootschappen bij een statutenwijziging", () => {
    expect(relevanteBriefCategorieen("aanpassing-statuten-vennootschap")).toEqual(["vennootschappen"]);
  });

  it("kiest de testament-categorie bij een testamentdossier", () => {
    expect(relevanteBriefCategorieen("keuzetestament")).toEqual(["testament"]);
    expect(relevanteBriefCategorieen("testament-gezinswoning")).toEqual(["testament"]);
  });

  it("sluit akteontwerp-mails uit zolang het ontwerp nog niet in opmaak is", () => {
    expect(relevanteBriefCategorieen("verkoop-zonder-krediet", "compromis-ontvangen")).not.toContain(
      "akteontwerp"
    );
    expect(relevanteBriefCategorieen("verkoop-zonder-krediet", "opzoekingen-lopend")).not.toContain(
      "akteontwerp"
    );
  });

  it("neemt akteontwerp-mails weer op vanaf de ontwerpfase", () => {
    expect(relevanteBriefCategorieen("verkoop-zonder-krediet", "ontwerp-in-opmaak")).toContain(
      "akteontwerp"
    );
  });

  it("zonder status blijft de volledige lijst van het dossiertype behouden", () => {
    expect(relevanteBriefCategorieen("verkoop-zonder-krediet")).toContain("akteontwerp");
  });
});

describe("stelModelmailsSamenAutonoom", () => {
  it("vult de relevante verkoopmails in met het gekende adres van het goed", () => {
    const resultaat = stelModelmailsSamenAutonoom(maakDossier(), seedBrieven);
    expect(resultaat.categorieen).toContain("verkoop");
    expect(resultaat.mails.length).toBeGreaterThan(0);
    const samengevoegd = resultaat.mails.map((m) => m.ingevuld.tekst).join("\n");
    expect(samengevoegd).toContain("Brusselsesteenweg 100");
  });

  it("surfaceert niet-afleidbare parameters als onzekerheden per mail", () => {
    const resultaat = stelModelmailsSamenAutonoom(maakDossier(), seedBrieven);
    // De per-ontvanger {{naam}} kan bij meerdere partijen niet eenduidig worden
    // ingevuld en moet dus als onzekerheid opduiken.
    expect(resultaat.mails.some((m) => m.onzekerheden.length > 0)).toBe(true);
  });

  it("geeft enkel NL-mails terug bij de standaardtaal", () => {
    const resultaat = stelModelmailsSamenAutonoom(maakDossier(), seedBrieven);
    expect(resultaat.mails.every((m) => (m.brief.taal ?? "nl") === "nl")).toBe(true);
  });

  it("vult de testament-mails in bij een testamentdossier", () => {
    const resultaat = stelModelmailsSamenAutonoom(maakDossier({ dossiertype: "keuzetestament" }), seedBrieven);
    expect(resultaat.categorieen).toEqual(["testament"]);
    expect(resultaat.mails.length).toBeGreaterThan(0);
  });

  it("signaleert open onzekerheid wanneer er geen modelmail in de gevraagde taal bestaat voor de categorie", () => {
    const resultaat = stelModelmailsSamenAutonoom(maakDossier({ dossiertype: "keuzetestament" }), seedBrieven, "en");
    expect(resultaat.mails).toEqual([]);
    expect(resultaat.onzekerheden.length).toBeGreaterThan(0);
  });

  it("signaleert wanneer er geen modelmail in de gevraagde taal bestaat", () => {
    const resultaat = stelModelmailsSamenAutonoom(maakDossier(), seedBrieven, "en");
    // Er bestaan wel EN-mails voor akteontwerp/verkoop; controleer dat de filtering op taal werkt.
    expect(resultaat.mails.every((m) => (m.brief.taal ?? "nl") === "en")).toBe(true);
  });
});

describe("stelModelmailsSamenAutonoom — taal van de confrater-brief", () => {
  const confraterTalen = (taal: "nl" | "fr", confraterTaal: "nl" | "fr") =>
    stelModelmailsSamenAutonoom(maakDossier(), seedBrieven, taal, undefined, confraterTaal)
      .mails.filter((m) => /confrater|notaris/.test(m.brief.ontvanger.toLowerCase()))
      .map((m) => m.brief.taal ?? "nl");

  it("schrijft de confrater in Vlaanderen in het NL, ook bij een FR-model", () => {
    const talen = confraterTalen("fr", "nl");
    expect(talen.length).toBeGreaterThan(0);
    expect(talen.every((t) => t === "nl")).toBe(true);
  });

  it("schrijft de confrater in Wallonië in het FR, ook bij een NL-model", () => {
    const talen = confraterTalen("nl", "fr");
    expect(talen.length).toBeGreaterThan(0);
    expect(talen.every((t) => t === "fr")).toBe(true);
  });

  it("volgt in Brussel de taal van het model (confraterTaal = documenttaal)", () => {
    expect(confraterTalen("fr", "fr").every((t) => t === "fr")).toBe(true);
  });
});
