// src/lib/content/csv.test.ts
import { expect, test } from "bun:test";
import { buildContentCsv, parseContentRows, parseCsv } from "./csv";

test("parseCsv: champs simples, quotés, quotes échappées, retour ligne quoté, CRLF", () => {
  expect(parseCsv("a,b\nc,d")).toEqual([
    ["a", "b"],
    ["c", "d"],
  ]);
  expect(parseCsv('a,"b,c"\r\nd,"e ""f"""')).toEqual([
    ["a", "b,c"],
    ["d", 'e "f"'],
  ]);
  expect(parseCsv('"l1\nl2",x')).toEqual([["l1\nl2", "x"]]);
  expect(parseCsv("")).toEqual([]);
  expect(parseCsv("a,b\n")).toEqual([["a", "b"]]); // ligne vide finale ignorée
});

test("buildContentCsv: en-têtes, échappement, champs vides", () => {
  const csv = buildContentCsv([
    {
      title: "Guide, complet",
      status: "writing",
      primaryKeywordTerm: "audit énergie",
      secondaryKeywordTerms: ["a", "b"],
      lang: "fr",
      country: "FR",
      assignee: null,
      dueDate: "2026-07-01",
      url: null,
    },
  ]);
  const [header, row] = csv.trim().split("\n");
  expect(header).toBe(
    "Titre,Statut,Mot-clé principal,Mots-clés secondaires,Langue,Pays,Assigné,Échéance,URL",
  );
  expect(row).toBe(
    '"Guide, complet",writing,audit énergie,a|b,fr,FR,,2026-07-01,',
  );
});

test("round-trip: build → parse → parseContentRows", () => {
  const csv = buildContentCsv([
    {
      title: "Page X",
      status: "brief",
      primaryKeywordTerm: "kw",
      secondaryKeywordTerms: [],
      lang: "fr",
      country: "FR",
      assignee: "bob",
      dueDate: null,
      url: "https://a.fr/x",
    },
  ]);
  const { rows, errors } = parseContentRows(parseCsv(csv));
  expect(errors).toEqual([]);
  expect(rows).toEqual([
    {
      title: "Page X",
      status: "brief",
      primaryKeywordTerm: "kw",
      secondaryKeywordTerms: [],
      lang: "fr",
      country: "FR",
      assignee: "bob",
      dueDate: null,
      url: "https://a.fr/x",
    },
  ]);
});

test("parseContentRows: en-têtes insensibles casse/ordre, colonnes inconnues ignorées, défauts", () => {
  const { rows, errors } = parseContentRows([
    ["statut", "TITRE", "bidule"],
    ["", "Mon titre", "x"],
  ]);
  expect(errors).toEqual([]);
  expect(rows[0].title).toBe("Mon titre");
  expect(rows[0].status).toBe("idea"); // statut vide → idea
  expect(rows[0].primaryKeywordTerm).toBe(null);
});

test("parseContentRows: erreurs — titre requis, statut invalide, date invalide", () => {
  const { rows, errors } = parseContentRows([
    ["Titre", "Statut", "Échéance"],
    ["", "idea", ""],
    ["Ok", "pas-un-statut", ""],
    ["Ok2", "idea", "07/2026"],
    ["Ok3", "review", "2026-07-01"],
  ]);
  expect(rows).toHaveLength(1);
  expect(rows[0].title).toBe("Ok3");
  expect(errors.map((e) => e.line)).toEqual([2, 3, 4]); // 1-indexé, en-tête = ligne 1
});
