import { describe, test, expect } from "bun:test";
import {
	formatDate,
	getGradeColor,
	getPerformanceMessage,
	getStreakMessage,
} from "$lib/utils/stats";

describe("getGradeColor", () => {
	test("S++ → purple", () => {
		expect(getGradeColor("S++")).toBe("text-purple-600 bg-purple-100");
	});

	test("S+ → yellow", () => {
		expect(getGradeColor("S+")).toBe("text-yellow-600 bg-yellow-100");
	});

	test("A+ → green", () => {
		expect(getGradeColor("A+")).toBe("text-green-600 bg-green-100");
	});

	test("A → light green", () => {
		expect(getGradeColor("A")).toBe("text-green-500 bg-green-50");
	});

	test("B+ → blue", () => {
		expect(getGradeColor("B+")).toBe("text-blue-600 bg-blue-100");
	});

	test("B → light blue", () => {
		expect(getGradeColor("B")).toBe("text-blue-500 bg-blue-50");
	});

	test("C+ → orange", () => {
		expect(getGradeColor("C+")).toBe("text-orange-600 bg-orange-100");
	});

	test("C → red", () => {
		expect(getGradeColor("C")).toBe("text-red-600 bg-red-100");
	});

	test("unknown grade → gray fallback", () => {
		expect(getGradeColor("X")).toBe("text-gray-600 bg-gray-100");
		expect(getGradeColor("")).toBe("text-gray-600 bg-gray-100");
	});
});

describe("formatDate", () => {
	test("formats a mid-year date", () => {
		expect(formatDate("2024-07-04")).toBe("Jul 4");
	});

	test("formats a January date", () => {
		expect(formatDate("2024-01-15")).toBe("Jan 15");
	});

	test("formats the last day of the year", () => {
		expect(formatDate("2023-12-31")).toBe("Dec 31");
	});

	test("formats a single-digit day without leading zero", () => {
		expect(formatDate("2025-03-01")).toBe("Mar 1");
	});

	test("year in input does not appear in output", () => {
		expect(formatDate("2024-06-20")).not.toContain("2024");
	});
});

describe("getStreakMessage", () => {
	test("0 → prompt to start", () => {
		expect(getStreakMessage(0)).toBe("Start your streak today!");
	});

	test("1 → encouragement", () => {
		expect(getStreakMessage(1)).toBe("Keep it going!");
	});

	test("2 → X days strong", () => {
		expect(getStreakMessage(2)).toBe("2 days strong!");
	});

	test("6 → X days strong (upper bound of that range)", () => {
		expect(getStreakMessage(6)).toBe("6 days strong!");
	});

	test("7 → week streak message", () => {
		expect(getStreakMessage(7)).toBe("7 day streak - amazing!");
	});

	test("29 → upper bound of week-streak range", () => {
		expect(getStreakMessage(29)).toBe("29 day streak - amazing!");
	});

	test("30 → unstoppable message", () => {
		expect(getStreakMessage(30)).toBe("30 days - you're unstoppable!");
	});

	test("100 → unstoppable message", () => {
		expect(getStreakMessage(100)).toBe("100 days - you're unstoppable!");
	});
});

describe("getPerformanceMessage", () => {
	test("≤ 2 guesses → exceptional", () => {
		expect(getPerformanceMessage(1)).toBe("Exceptional performance!");
		expect(getPerformanceMessage(2)).toBe("Exceptional performance!");
	});

	test("≤ 4 guesses → great", () => {
		expect(getPerformanceMessage(2.1)).toBe("Great performance!");
		expect(getPerformanceMessage(4)).toBe("Great performance!");
	});

	test("≤ 6 guesses → good", () => {
		expect(getPerformanceMessage(4.1)).toBe("Good performance!");
		expect(getPerformanceMessage(6)).toBe("Good performance!");
	});

	test("≤ 8 guesses → room for improvement", () => {
		expect(getPerformanceMessage(6.1)).toBe("Room for improvement!");
		expect(getPerformanceMessage(8)).toBe("Room for improvement!");
	});

	test("> 8 guesses → keep practicing", () => {
		expect(getPerformanceMessage(8.1)).toBe("Keep practicing!");
		expect(getPerformanceMessage(20)).toBe("Keep practicing!");
	});
});
