import type { IShareData } from "@ax/api";

import { getShareTokenInfo } from "@ax/helpers";

const makeShareData = (overrides: Partial<IShareData> = {}): IShareData => ({
	entity: "test-entity",
	daysValid: 30,
	startDate: "2026-03-01T00:00:00.000Z",
	endDate: "2026-03-31T00:00:00.000Z",
	visitCount: 5,
	...overrides,
});

describe("getShareTokenInfo", () => {
	describe("token expiration", () => {
		it("should detect an active token", () => {
			const now = new Date("2026-03-15");
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.tokenHasExpired).toBe(false);
		});

		it("should detect an expired token", () => {
			const now = new Date("2026-04-01");
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.tokenHasExpired).toBe(true);
		});

		it("should detect expiration on the exact end date", () => {
			const now = new Date("2026-03-31T12:00:00.000Z");
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.tokenHasExpired).toBe(true);
		});
	});

	describe("days until expiration", () => {
		it("should return remaining days for an active token", () => {
			const now = new Date("2026-03-21");
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.validTokenDaysUntilExpires).toBe(10);
		});

		it("should return 0 for an expired token", () => {
			const now = new Date("2026-05-01");
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.validTokenDaysUntilExpires).toBe(0);
		});

		it("should return 0 on the exact end date", () => {
			const now = new Date("2026-03-31");
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.validTokenDaysUntilExpires).toBe(0);
		});
	});

	describe("token renewal", () => {
		it("should allow renewal when less than 14 days remain", () => {
			const now = new Date("2026-03-20"); // 11 days left
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.tokenCanBeRenewed).toBe(true);
		});

		it("should not allow renewal when 14 or more days remain", () => {
			const now = new Date("2026-03-10"); // 21 days left
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.tokenCanBeRenewed).toBe(false);
		});

		it("should not allow renewal for an expired token", () => {
			const now = new Date("2026-04-15");
			const result = getShareTokenInfo(makeShareData(), now);

			expect(result.tokenCanBeRenewed).toBe(false);
		});
	});

	describe("formatted expiration date", () => {
		it("should format the expiration date", () => {
			const result = getShareTokenInfo(makeShareData());

			expect(result.tokenExpirationDate).toBe("March 31, 2026");
		});
	});
});
