/* @vitest-environment node */

import { describe, it, expect } from "vitest";
import {
	isValidIsoDateYmd,
	normalizeIsoDateYmdOrNull,
	compareIsoDatesYmd,
	isInvalidIsoDateRange,
	formatIsoDateDe,
	formatIsoDateRangeLabelDe,
	toIsoDateYmdFromDate,
	toDateFromIsoDateYmd,
} from "./dateRange.js";

describe("lib/frontend/search/dateRange", () => {
	describe("isValidIsoDateYmd", () => {
		it("accepts strict YYYY-MM-DD", () => {
			expect(isValidIsoDateYmd("2025-12-01")).toBe(true);
			expect(isValidIsoDateYmd("2025-01-31")).toBe(true);
		});

		it("rejects invalid formats and obvious invalid ranges", () => {
			expect(isValidIsoDateYmd("2025/12/01")).toBe(false);
			expect(isValidIsoDateYmd("2025-1-01")).toBe(false);
			expect(isValidIsoDateYmd("2025-01-1")).toBe(false);

			expect(isValidIsoDateYmd("2025-13-01")).toBe(false);
			expect(isValidIsoDateYmd("2025-00-01")).toBe(false);
			expect(isValidIsoDateYmd("2025-12-00")).toBe(false);
			expect(isValidIsoDateYmd("2025-12-32")).toBe(false);
		});
	});

	describe("normalizeIsoDateYmdOrNull", () => {
		it("trims and returns null for invalid values", () => {
			expect(normalizeIsoDateYmdOrNull(" 2025-12-01 ")).toBe("2025-12-01");
			expect(normalizeIsoDateYmdOrNull("")).toBe(null);
			expect(normalizeIsoDateYmdOrNull("2025/12/01")).toBe(null);
			expect(normalizeIsoDateYmdOrNull(null)).toBe(null);
		});
	});

	describe("compareIsoDatesYmd", () => {
		it("compares lexicographically", () => {
			expect(compareIsoDatesYmd("2025-01-01", "2025-01-01")).toBe(0);
			expect(compareIsoDatesYmd("2025-01-01", "2025-01-02")).toBe(-1);
			expect(compareIsoDatesYmd("2025-12-31", "2025-01-01")).toBe(1);
		});
	});

	describe("isInvalidIsoDateRange", () => {
		it("is false for open ranges and equal dates", () => {
			expect(isInvalidIsoDateRange("2025-12-01", null)).toBe(false);
			expect(isInvalidIsoDateRange(null, "2025-12-31")).toBe(false);
			expect(isInvalidIsoDateRange("2025-12-01", "2025-12-01")).toBe(false);
		});

		it("is true when from > to", () => {
			expect(isInvalidIsoDateRange("2025-12-31", "2025-12-01")).toBe(true);
		});
	});

	describe("formatIsoDateDe / formatIsoDateRangeLabelDe", () => {
		it("formats single dates as DD.MM.YYYY", () => {
			expect(formatIsoDateDe("2025-12-01")).toBe("01.12.2025");
			expect(formatIsoDateDe("invalid")).toBe(null);
		});

		it("formats date range labels", () => {
			expect(
				formatIsoDateRangeLabelDe({ from: "2025-12-01", to: "2025-12-31" })
			).toBe("01.12.2025 – 31.12.2025");

			expect(
				formatIsoDateRangeLabelDe({ from: "2025-12-01", to: "2025-12-01" })
			).toBe("01.12.2025");

			expect(formatIsoDateRangeLabelDe({ from: "2025-12-01", to: null })).toBe(
				"ab 01.12.2025"
			);

			expect(formatIsoDateRangeLabelDe({ from: null, to: "2025-12-31" })).toBe(
				"bis 31.12.2025"
			);

			expect(formatIsoDateRangeLabelDe({ from: null, to: null })).toBe(null);
		});
	});

	describe("toIsoDateYmdFromDate / toDateFromIsoDateYmd", () => {
		it("converts dates without timezone drift", () => {
			const d = new Date(2026, 0, 14); // 14 Jan 2026 (local)
			expect(toIsoDateYmdFromDate(d)).toBe("2026-01-14");

			const back = toDateFromIsoDateYmd("2026-01-14");
			expect(back).not.toBe(null);
			expect(back.getFullYear()).toBe(2026);
			expect(back.getMonth()).toBe(0);
			expect(back.getDate()).toBe(14);
		});
	});
});
