import { describe, expect, it } from "vitest";

import { EXPIRY_NOTICE_DAYS, expiryNoticeDays, expiryNoticeLabel } from "./contract-ui";

const inDays = (days: number): string =>
  // Half a day past the boundary so ceil() lands on `days` regardless of the
  // clock at test time.
  new Date(Date.now() + (days - 0.5) * 86_400_000).toISOString();

const contract = (over: Record<string, unknown> = {}) =>
  ({
    status: "CONTRACT_ACTIVE",
    contractValidUntil: inDays(5),
    ...over,
  }) as never;

describe("expiryNoticeDays", () => {
  it("counts the days left once inside the notice window", () => {
    expect(expiryNoticeDays(contract({ contractValidUntil: inDays(5) }))).toBe(5);
    expect(
      expiryNoticeDays(
        contract({ contractValidUntil: inDays(EXPIRY_NOTICE_DAYS) }),
      ),
    ).toBe(EXPIRY_NOTICE_DAYS);
  });

  it("stays silent while the contract is further out than the window", () => {
    expect(
      expiryNoticeDays(
        contract({ contractValidUntil: inDays(EXPIRY_NOTICE_DAYS + 1) }),
      ),
    ).toBeNull();
  });

  it("stays silent for a contract with no validity date", () => {
    expect(expiryNoticeDays(contract({ contractValidUntil: null }))).toBeNull();
  });

  it("stays silent once the date has passed — that is expiry, not a warning", () => {
    expect(expiryNoticeDays(contract({ contractValidUntil: inDays(-1) }))).toBeNull();
  });

  it("stays silent on contracts that are already over", () => {
    for (const status of ["EXPIRED", "CANCELLED", "REJECTED", "CONTRACT_CLOSED"]) {
      expect(expiryNoticeDays(contract({ status }))).toBeNull();
    }
  });
});

describe("expiryNoticeLabel", () => {
  it("reads naturally at the edges", () => {
    expect(expiryNoticeLabel(0)).toBe("Expires today");
    expect(expiryNoticeLabel(1)).toBe("1 day left");
    expect(expiryNoticeLabel(10)).toBe("10 days left");
  });
});
