import { describe, it, expect, beforeEach, vi } from "vitest";
import { formatRelative, formatDateTime, formatDate } from "../date.js";

describe("date utils", () => {
  beforeEach(() => {
    vi.useFakeTimers();
    // Use local time to match how parseDate works
    vi.setSystemTime(new Date(Date.UTC(2026, 5, 8, 12, 0, 0)));
  });

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

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

    it("returns original string for invalid dates", () => {
      expect(formatRelative("invalid")).toBe("invalid");
    });

    it("formats just now", () => {
      expect(formatRelative("2026-06-08 12:00:00")).toBe("just now");
    });

    it("formats seconds ago", () => {
      expect(formatRelative("2026-06-08 11:59:50")).toMatch(/\d+ sec ago/);
    });

    it("formats minutes ago", () => {
      expect(formatRelative("2026-06-08 11:55:00")).toMatch(/\d+ min ago/);
    });

    it("formats hours ago", () => {
      expect(formatRelative("2026-06-08 10:00:00")).toMatch(/\d+ hour(s)? ago/);
    });

    it("formats days ago", () => {
      expect(formatRelative("2026-06-05 12:00:00")).toMatch(/\d+ day(s)? ago/);
    });

    it("formats weeks ago", () => {
      expect(formatRelative("2026-05-25 12:00:00")).toMatch(/\d+ week(s)? ago/);
    });

    it("formats months ago", () => {
      expect(formatRelative("2026-03-08 12:00:00")).toMatch(/\d+ month(s)? ago/);
    });

    it("formats years ago", () => {
      expect(formatRelative("2024-06-08 12:00:00")).toMatch(/\d+ year(s)? ago/);
    });
  });

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

    it("returns original string for invalid dates", () => {
      expect(formatDateTime("invalid")).toBe("invalid");
    });

    it("formats MySQL datetime format", () => {
      const result = formatDateTime("2026-06-08 12:00:00");
      expect(result).toContain("Jun");
      expect(result).toContain("2026");
      expect(result).toMatch(/:\d{2}$/);
    });

    it("formats ISO date strings", () => {
      const result = formatDateTime("2026-06-08T12:00:00Z");
      expect(result).toContain("Jun");
      expect(result).toContain("2026");
    });
  });

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

    it("returns original string for invalid dates", () => {
      expect(formatDate("invalid")).toBe("invalid");
    });

    it("formats date without time", () => {
      const result = formatDate("2026-06-08 12:00:00");
      expect(result).toBe("Jun 8, 2026");
    });
  });
});
