import { describe, it, expect } from "vitest";
import { formatDuration, formatTime, formatDate, isDayChange } from "./index.js";

describe("formatDuration", () => {
  it("formats zero minutes", () => {
    expect(formatDuration(0)).toBe("0h 0m");
  });

  it("formats minutes only", () => {
    expect(formatDuration(45)).toBe("0h 45m");
  });

  it("formats hours and minutes", () => {
    expect(formatDuration(150)).toBe("2h 30m");
  });

  it("formats days, hours, and minutes", () => {
    // 1 day + 5 hours + 12 minutes = 1572 minutes
    expect(formatDuration(1572)).toBe("1d 2h 12m");
  });

  it("formats in Russian locale (Angular parity: 'Xч. Xмин.')", () => {
    expect(formatDuration(150, "ru")).toBe("2ч. 30мин.");
  });

  it("formats days in Russian locale (Angular parity: 'Xд. Xч. Xмин.')", () => {
    expect(formatDuration(1572, "ru")).toBe("1д. 2ч. 12мин.");
  });

  it("returns 'Unknown' for negative values", () => {
    expect(formatDuration(-1)).toBe("Unknown");
  });

  it("returns 'Неизвестно' for negative values in Russian", () => {
    expect(formatDuration(-1, "ru")).toBe("Неизвестно");
  });

  it("handles exact hour boundaries", () => {
    expect(formatDuration(60)).toBe("1h 0m");
    expect(formatDuration(120)).toBe("2h 0m");
  });

  it("handles exact day boundaries", () => {
    expect(formatDuration(1440)).toBe("1d 0h 0m");
  });
});

describe("formatTime", () => {
  it("formats ISO string to HH:mm", () => {
    // Use a fixed date with explicit time to avoid timezone issues
    const d = new Date(2025, 0, 15, 10, 30);
    expect(formatTime(d)).toBe("10:30");
  });

  it("pads single-digit hours and minutes", () => {
    const d = new Date(2025, 0, 15, 3, 5);
    expect(formatTime(d)).toBe("03:05");
  });

  it("handles midnight", () => {
    const d = new Date(2025, 0, 15, 0, 0);
    expect(formatTime(d)).toBe("00:00");
  });

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

  it("formats Date objects", () => {
    const d = new Date(2025, 0, 15, 14, 45);
    expect(formatTime(d)).toBe("14:45");
  });
});

describe("formatDate", () => {
  it("formats a date in English", () => {
    const result = formatDate(new Date(2025, 0, 15), "en");
    expect(result).toContain("January");
    expect(result).toContain("15");
    expect(result).toContain("2025");
  });

  it("formats a date in Russian", () => {
    const result = formatDate(new Date(2025, 0, 15), "ru");
    expect(result).toContain("15");
    expect(result).toContain("2025");
    // Russian month name for January contains "январ"
    expect(result.toLowerCase()).toContain("январ");
  });

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

  it("defaults to English locale", () => {
    const result = formatDate(new Date(2025, 0, 15));
    expect(result).toContain("January");
  });
});

describe("isDayChange", () => {
  it("returns 0 for same day", () => {
    expect(
      isDayChange("2025-01-15T10:00:00", "2025-01-15T23:00:00"),
    ).toBe(0);
  });

  it("returns 1 for next day", () => {
    expect(
      isDayChange(
        new Date(2025, 0, 15, 23, 0),
        new Date(2025, 0, 16, 1, 0),
      ),
    ).toBe(1);
  });

  it("returns -1 for previous day", () => {
    expect(
      isDayChange(
        new Date(2025, 0, 16, 1, 0),
        new Date(2025, 0, 15, 23, 0),
      ),
    ).toBe(-1);
  });

  it("returns 0 for invalid dates", () => {
    expect(isDayChange("invalid", "also-invalid")).toBe(0);
  });

  it("returns 2 for two days later", () => {
    expect(
      isDayChange(
        new Date(2025, 0, 15),
        new Date(2025, 0, 17),
      ),
    ).toBe(2);
  });
});
