import { describe, it, expect } from "vitest";
import {
  groupByBatch,
  formatDate,
  toDateInputValue,
  dateInputToIso,
} from "./pibiSectionHelpers";

// ── groupByBatch ───────────────────────────────────────────────────────────────

describe("groupByBatch", () => {
  it("returns empty array for no rows", () => {
    expect(groupByBatch([])).toEqual([]);
  });

  it("groups rows with the same orderedAt into one batch", () => {
    const orderedAt = "2026-05-01T00:00:00.000Z";
    const rows = [
      { id: "1", measureName: "CWI", orderedAt, completedAt: null },
      { id: "2", measureName: "ASHP", orderedAt, completedAt: null },
    ];
    const batches = groupByBatch(rows);
    expect(batches).toHaveLength(1);
    expect(batches[0].orderedAt).toBe(orderedAt);
    expect(batches[0].rows).toHaveLength(2);
  });

  it("creates separate batches for different orderedAt values", () => {
    const rows = [
      { id: "1", measureName: "CWI", orderedAt: "2026-05-01T00:00:00.000Z", completedAt: null },
      { id: "2", measureName: "ASHP", orderedAt: "2026-05-15T00:00:00.000Z", completedAt: null },
    ];
    const batches = groupByBatch(rows);
    expect(batches).toHaveLength(2);
  });

  it("preserves insertion order of first-seen orderedAt keys", () => {
    const first = "2026-04-01T00:00:00.000Z";
    const second = "2026-05-01T00:00:00.000Z";
    const rows = [
      { id: "1", measureName: "CWI", orderedAt: first, completedAt: null },
      { id: "2", measureName: "ASHP", orderedAt: second, completedAt: null },
      { id: "3", measureName: "EWI", orderedAt: first, completedAt: null },
    ];
    const batches = groupByBatch(rows);
    expect(batches[0].orderedAt).toBe(first);
    expect(batches[0].rows).toHaveLength(2);
    expect(batches[1].orderedAt).toBe(second);
  });
});

// ── formatDate ─────────────────────────────────────────────────────────────────

describe("formatDate", () => {
  it("returns em-dash for null", () => {
    expect(formatDate(null)).toBe("—");
  });

  it("returns em-dash for empty string", () => {
    expect(formatDate("")).toBe("—");
  });

  it("formats a valid ISO date as dd Mon yyyy in en-GB locale", () => {
    expect(formatDate("2026-05-06T00:00:00.000Z")).toBe("06 May 2026");
  });

  it("returns em-dash for an unparseable string", () => {
    expect(formatDate("not-a-date")).toBe("—");
  });
});

// ── toDateInputValue ───────────────────────────────────────────────────────────

describe("toDateInputValue", () => {
  it("returns empty string for null", () => {
    expect(toDateInputValue(null)).toBe("");
  });

  it("converts ISO to YYYY-MM-DD using UTC date parts", () => {
    expect(toDateInputValue("2026-05-06T00:00:00.000Z")).toBe("2026-05-06");
  });

  it("zero-pads month and day", () => {
    expect(toDateInputValue("2026-01-09T00:00:00.000Z")).toBe("2026-01-09");
  });

  it("returns empty string for unparseable input", () => {
    expect(toDateInputValue("not-a-date")).toBe("");
  });
});

// ── dateInputToIso ─────────────────────────────────────────────────────────────

describe("dateInputToIso", () => {
  it("returns null for empty string", () => {
    expect(dateInputToIso("")).toBeNull();
  });

  it("converts YYYY-MM-DD to midnight UTC ISO string", () => {
    expect(dateInputToIso("2026-05-06")).toBe("2026-05-06T00:00:00.000Z");
  });

  it("round-trips with toDateInputValue", () => {
    const iso = "2026-03-15T00:00:00.000Z";
    expect(dateInputToIso(toDateInputValue(iso))).toBe(iso);
  });
});
