import { describe, it, expect } from "vitest";
import {
  formatDate,
  formatTime,
  getDateGroupLabel,
  isPastTarget,
  isApproachingTarget,
} from "./date-format";

describe("date-format utils", (): void => {
  describe("formatDate", (): void => {
    it("should format date in readable format", (): void => {
      // Use explicit time to avoid timezone issues
      const date = new Date("2026-01-29T12:00:00");
      const result = formatDate(date);
      expect(result).toMatch(/Jan/);
      expect(result).toMatch(/2026/);
      // Note: Day might be 28 or 29 depending on timezone
      expect(result).toMatch(/\d{1,2}/);
    });

    it("should handle invalid dates", (): void => {
      const result = formatDate(new Date("invalid"));
      expect(result).toBe("Invalid Date");
    });
  });

  describe("formatTime", (): void => {
    it("should format time in 12-hour format", (): void => {
      const date = new Date("2026-01-29T14:30:00");
      const result = formatTime(date);
      expect(result).toMatch(/\d{1,2}:\d{2} [AP]M/i);
    });

    it("should handle invalid time", (): void => {
      const result = formatTime(new Date("invalid"));
      expect(result).toBe("Invalid Time");
    });
  });

  describe("getDateGroupLabel", (): void => {
    const today = new Date("2026-01-28T12:00:00");

    it("should return 'Today' for today's date", (): void => {
      const date = new Date("2026-01-28T14:00:00");
      const result = getDateGroupLabel(date, today);
      expect(result).toBe("Today");
    });

    it("should return 'Tomorrow' for tomorrow's date", (): void => {
      const date = new Date("2026-01-29T10:00:00");
      const result = getDateGroupLabel(date, today);
      expect(result).toBe("Tomorrow");
    });

    it("should return 'This Week' for dates within 7 days", (): void => {
      const date = new Date("2026-02-02T10:00:00");
      const result = getDateGroupLabel(date, today);
      expect(result).toBe("This Week");
    });

    it("should return 'Next Week' for dates 7-14 days out", (): void => {
      const date = new Date("2026-02-08T10:00:00");
      const result = getDateGroupLabel(date, today);
      expect(result).toBe("Next Week");
    });

    it("should return 'Later' for dates beyond 2 weeks", (): void => {
      const date = new Date("2026-03-15T10:00:00");
      const result = getDateGroupLabel(date, today);
      expect(result).toBe("Later");
    });
  });

  describe("isPastTarget", (): void => {
    const now = new Date("2026-01-28T12:00:00");

    it("should return true for past dates", (): void => {
      const pastDate = new Date("2026-01-27T10:00:00");
      expect(isPastTarget(pastDate, now)).toBe(true);
    });

    it("should return false for future dates", (): void => {
      const futureDate = new Date("2026-01-29T10:00:00");
      expect(isPastTarget(futureDate, now)).toBe(false);
    });

    it("should return false for current time", (): void => {
      expect(isPastTarget(now, now)).toBe(false);
    });
  });

  describe("isApproachingTarget", (): void => {
    const now = new Date("2026-01-28T12:00:00");

    it("should return true for dates within 24 hours", (): void => {
      const soonDate = new Date("2026-01-29T10:00:00");
      expect(isApproachingTarget(soonDate, now)).toBe(true);
    });

    it("should return false for dates beyond 24 hours", (): void => {
      const laterDate = new Date("2026-01-30T14:00:00");
      expect(isApproachingTarget(laterDate, now)).toBe(false);
    });

    it("should return false for past dates", (): void => {
      const pastDate = new Date("2026-01-27T10:00:00");
      expect(isApproachingTarget(pastDate, now)).toBe(false);
    });
  });
});
