import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { computeDateRange, buildMonthOptions } from "./dateRange";

describe("computeDateRange", () => {
  beforeEach(() => {
    // Fix "now" to 2025-07-15 for deterministic tests
    vi.useFakeTimers();
    vi.setSystemTime(new Date(2025, 6, 15)); // July 15, 2025
  });

  afterEach(() => {
    vi.useRealTimers();
  });

  it('returns empty object for "all" period', () => {
    expect(computeDateRange("all")).toEqual({});
  });

  it('returns custom range for "custom" period', () => {
    expect(computeDateRange("custom", "2025-01-01", "2025-06-30")).toEqual({
      dateFrom: "2025-01-01",
      dateTo: "2025-06-30",
    });
  });

  it('falls back to default when "custom" has missing dates', () => {
    const result = computeDateRange("custom");
    // Should fall through to default (same as "month")
    expect(result.dateFrom).toBe("2025-07-01");
    expect(result.dateTo).toBe("2025-07-15");
  });

  it('computes "month" period (first of current month to today)', () => {
    const result = computeDateRange("month");
    expect(result).toEqual({ dateFrom: "2025-07-01", dateTo: "2025-07-15" });
  });

  it('computes "3months" period (3 months back)', () => {
    const result = computeDateRange("3months");
    expect(result).toEqual({ dateFrom: "2025-05-01", dateTo: "2025-07-15" });
  });

  it('computes "6months" period (6 months back)', () => {
    const result = computeDateRange("6months");
    expect(result).toEqual({ dateFrom: "2025-02-01", dateTo: "2025-07-15" });
  });

  it('computes "year" period (Jan 1st of current year)', () => {
    const result = computeDateRange("year");
    expect(result).toEqual({ dateFrom: "2025-01-01", dateTo: "2025-07-15" });
  });

  it('computes "12months" period (12 months back)', () => {
    const result = computeDateRange("12months");
    expect(result).toEqual({ dateFrom: "2024-08-01", dateTo: "2025-07-15" });
  });

  it("handles January rollover for 3months period", () => {
    vi.setSystemTime(new Date(2025, 1, 10)); // Feb 10, 2025
    const result = computeDateRange("3months");
    expect(result).toEqual({ dateFrom: "2024-12-01", dateTo: "2025-02-10" });
  });

  it("handles January rollover for 6months period", () => {
    vi.setSystemTime(new Date(2025, 0, 20)); // Jan 20, 2025
    const result = computeDateRange("6months");
    expect(result).toEqual({ dateFrom: "2024-08-01", dateTo: "2025-01-20" });
  });

  it("handles January rollover for 12months period", () => {
    vi.setSystemTime(new Date(2025, 0, 5)); // Jan 5, 2025
    const result = computeDateRange("12months");
    expect(result).toEqual({ dateFrom: "2024-02-01", dateTo: "2025-01-05" });
  });
});

describe("buildMonthOptions", () => {
  beforeEach(() => {
    vi.useFakeTimers();
    vi.setSystemTime(new Date(2025, 6, 15)); // July 15, 2025
  });

  afterEach(() => {
    vi.useRealTimers();
  });

  it("returns 24 month options", () => {
    const options = buildMonthOptions("fr");
    expect(options).toHaveLength(24);
  });

  it("starts with the current month", () => {
    const options = buildMonthOptions("en");
    expect(options[0].key).toBe("2025-7");
    expect(options[0].value).toBe("2025-7");
  });

  it("ends 23 months ago", () => {
    const options = buildMonthOptions("en");
    expect(options[23].key).toBe("2023-8");
    expect(options[23].value).toBe("2023-8");
  });

  it("handles January rollover correctly", () => {
    vi.setSystemTime(new Date(2025, 0, 15)); // Jan 15, 2025
    const options = buildMonthOptions("en");
    expect(options[0].key).toBe("2025-1");
    expect(options[1].key).toBe("2024-12");
    expect(options[12].key).toBe("2024-1");
  });

  it("capitalizes the first letter of labels", () => {
    const options = buildMonthOptions("fr");
    for (const opt of options) {
      expect(opt.label[0]).toBe(opt.label[0].toUpperCase());
    }
  });

  it("labels contain year information", () => {
    const options = buildMonthOptions("en");
    expect(options[0].label).toContain("2025");
  });
});
