<script lang="ts">
	import { browser } from "$app/environment";
	import { onMount } from "svelte";
	import AuthModal from "$lib/components/AuthModal.svelte";
	import Container from "$lib/components/Container.svelte";
	import ProgressStatCard from "$lib/components/ProgressStatCard.svelte";
	import ActivityCalendar from "$lib/components/ActivityCalendar.svelte";
	import { bibleBooks } from "$lib/types/bible";

	type BookTier = "unseen" | "explored" | "mastered" | "perfect";

	type BookGridEntry = {
		bookId: string;
		tier: BookTier;
		avgGuesses: number | null;
		count: number;
	};

	type ChartPoint = {
		label: string;
		avgGuesses: number;
	};

	type SectionStat = {
		section: string;
		avgGuesses: number;
		count: number;
	};

	type Milestone = {
		id: string;
		name: string;
		emoji: string;
		description: string;
		achieved: boolean;
		achievedDate: string | null;
	};

	type ProgressData = {
		completions: Array<{ date: string; guessCount: number }>;
		chartPoints: ChartPoint[];
		bookGrid: BookGridEntry[];
		sectionStats: SectionStat[];
		testamentStats: {
			old: { avgGuesses: number; count: number } | null;
			new: { avgGuesses: number; count: number } | null;
		};
		totalSolves: number;
		bestStreak: number;
		currentStreak: number;
		booksExplored: number;
		booksMastered: number;
		booksPerfect: number;
		bestSingleGame: { date: string; bookName: string } | null;
		totalWords: number;
		streakMilestones: {
			days7: string | null;
			days14: string | null;
			days30: string | null;
		};
		milestones: Milestone[];
	};

	interface PageData {
		progress: ProgressData | null;
		error?: string;
		user?: any;
		session?: any;
		requiresAuth?: boolean;
	}

	let { data }: { data: PageData } = $props();

	let authModalOpen = $state(false);
	let anonymousId = $state("");

	function getOrCreateAnonymousId(): string {
		if (!browser) return "";
		const key = "bibdle-anonymous-id";
		let id = localStorage.getItem(key);
		if (!id) {
			id = crypto.randomUUID();
			localStorage.setItem(key, id);
		}
		return id;
	}

	function bookTileClass(tier: BookTier): string {
		switch (tier) {
			case "perfect":
				return "bg-emerald-500 text-white";
			case "mastered":
				return "bg-purple-600 text-white";
			case "explored":
				return "bg-blue-700 text-blue-100";
			default:
				return "bg-gray-700/50 text-gray-500";
		}
	}

	function formatDate(dateStr: string): string {
		const d = new Date(dateStr + "T00:00:00Z");
		return d.toLocaleDateString("en-US", {
			month: "short",
			day: "numeric",
			year: "numeric",
			timeZone: "UTC",
		});
	}

	onMount(() => {
		anonymousId = getOrCreateAnonymousId();
	});

	// Derived SVG chart values
	const chartPoints = $derived(data.progress?.chartPoints ?? []);
	const showChart = $derived(chartPoints.length >= 3);
	const maxGuesses = $derived(
		showChart ? Math.max(...chartPoints.map((p) => p.avgGuesses)) : 6,
	);
	const chartImproving = $derived(
		showChart &&
			chartPoints[chartPoints.length - 1].avgGuesses <
				chartPoints[0].avgGuesses,
	);

	function svgX(index: number, total: number): number {
		return (index / (total - 1)) * 360 + 20;
	}

	function svgY(avgGuesses: number, maxG: number): number {
		return 100 - ((maxG - avgGuesses) / (maxG - 1)) * 90 + 10;
	}

	const polylinePoints = $derived(
		showChart
			? chartPoints
					.map(
						(p, i) =>
							`${svgX(i, chartPoints.length)},${svgY(p.avgGuesses, maxGuesses)}`,
					)
					.join(" ")
			: "",
	);

	// Insights helpers
	const progress = $derived(data.progress);
	const bestSection = $derived(
		progress?.sectionStats.find((s) => s.count >= 3) ?? null,
	);
	const hardestSection = $derived.by(() => {
		if (!progress) return null;
		const eligible = progress.sectionStats.filter((s) => s.count >= 3);
		if (eligible.length === 0) return null;
		const last = eligible[eligible.length - 1];
		if (bestSection && last.section === bestSection.section) return null;
		return last;
	});

	const showInsights = $derived(
		progress !== null &&
			((progress.testamentStats.old !== null &&
				progress.testamentStats.new !== null) ||
				bestSection !== null),
	);

	function testamentComparison(
		old_: { avgGuesses: number; count: number } | null,
		new_: { avgGuesses: number; count: number } | null,
	): string | null {
		if (!old_ || !new_) return null;
		const ratio = old_.avgGuesses / new_.avgGuesses;
		if (ratio < 0.85) {
			const x = (new_.avgGuesses / old_.avgGuesses).toFixed(1);
			return `You're ${x}x faster at Old Testament books`;
		}
		if (ratio > 1.18) {
			const x = (old_.avgGuesses / new_.avgGuesses).toFixed(1);
			return `You're ${x}x faster at New Testament books`;
		}
		return "Your speed is similar for Old and New Testament books";
	}
</script>

<svelte:head>
	<title>Your Progress | Bibdle</title>
	<meta
		name="description"
		content="Track your Bible knowledge journey with Bibdle"
	/>
</svelte:head>

<div
	class="min-h-screen bg-linear-to-br from-gray-900 via-slate-900 to-gray-900 p-4 md:p-8"
>
	<div class="max-w-3xl mx-auto">
		<!-- Header -->
		<div class="text-center mb-6 md:mb-8">
			<h1 class="text-3xl md:text-4xl font-bold text-gray-100 mb-4">
				Your Progress
			</h1>

			<a href="/" class="p-2 px-20 w-full items-center text-gray-300">
				&larr; Back to Game
			</a>
		</div>

		{#if data.requiresAuth}
			<div class="text-center py-12">
				<div
					class="bg-blue-950/50 border border-blue-800/50 rounded-lg p-8 max-w-md mx-auto backdrop-blur-sm"
				>
					<h2 class="text-2xl font-bold text-blue-200 mb-4">
						Authentication Required
					</h2>
					<p class="text-blue-300 mb-6">
						You must be logged in to see your progress.
					</p>
					<div class="flex flex-col gap-3">
						<button
							onclick={() => (authModalOpen = true)}
							class="inline-flex items-center justify-center px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium"
						>
							Sign In / Sign Up
						</button>
						<a
							href="/"
							class="inline-flex items-center justify-center px-6 py-3 bg-gray-700 text-white rounded-lg hover:bg-gray-600 transition-colors font-medium"
						>
							&larr; Back to Game
						</a>
					</div>
				</div>
			</div>
		{:else if data.error}
			<div class="text-center py-12">
				<div
					class="bg-red-950/50 border border-red-800/50 rounded-lg p-6 max-w-md mx-auto backdrop-blur-sm"
				>
					<p class="text-red-300">{data.error}</p>
					<a
						href="/"
						class="mt-4 inline-block px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700 transition-colors"
					>
						Return to Game
					</a>
				</div>
			</div>
		{:else if !data.progress}
			<div class="text-center py-12">
				<Container class="p-8 max-w-md mx-auto">
					<div class="text-yellow-400 mb-4 text-lg">
						No progress yet.
					</div>
					<p class="text-gray-300 mb-6">
						Start playing to build your Bible knowledge journey!
					</p>
					<a
						href="/"
						class="inline-flex items-center px-6 py-2.5 bg-amber-600 text-white rounded-lg hover:bg-amber-700 transition-colors font-medium shadow-md"
					>
						Start Playing
					</a>
				</Container>
			</div>
		{:else}
			{@const prog = data.progress}

			<!-- Key Stats Row -->
			<div class="grid grid-cols-2 md:grid-cols-3 gap-3 md:gap-4 mb-6">
				<ProgressStatCard
					emoji="📅"
					value={String(prog.totalSolves)}
					label="Total Played"
					colorClass="text-blue-400"
				/>
				<ProgressStatCard
					emoji="📖"
					value={String(prog.booksExplored)}
					label="Books Explored"
					colorClass="text-teal-400"
					suffix="/ 66"
				/>
				<ProgressStatCard
					emoji="✍️"
					value={prog.totalWords.toLocaleString()}
					label="Words Read"
					colorClass="text-violet-400"
				/>
				<ProgressStatCard
					emoji="✝️"
					value={(((prog.totalSolves * 3) / 31102) * 100).toFixed(2) +
						"%"}
					label="Bible Read"
					colorClass="text-amber-400"
				/>
				<ProgressStatCard
					emoji="🏆"
					value={String(prog.booksMastered)}
					label="Books Mastered"
					colorClass="text-purple-400"
					suffix="/ 66"
				/>
				<ProgressStatCard
					emoji="⭐"
					value={String(prog.booksPerfect)}
					label="Books Perfected"
					colorClass="text-emerald-400"
					suffix="/ 66"
				/>
			</div>

			<!-- Bible Book Grid -->
			<div class="mb-6">
				<Container class="p-4 md:p-6 w-full">
					<h2
						class="text-xl font-bold text-gray-100 mb-3 w-full text-left"
					>
						Bible Books
					</h2>
					<!-- Legend -->
					<div class="flex flex-wrap gap-2 mb-3">
						<span
							class="flex items-center gap-1 text-xs text-gray-400"
						>
							<span
								class="inline-block w-5 h-5 rounded bg-blue-700"
							></span>
							Explored
						</span>
						<span
							class="flex items-center gap-1 text-xs text-gray-400"
						>
							<span
								class="inline-block w-5 h-5 rounded bg-purple-600"
							></span>
							Mastered
						</span>
						<span
							class="flex items-center gap-1 text-xs text-gray-400"
						>
							<span
								class="inline-block w-5 h-5 rounded bg-emerald-500"
							></span>
							Perfect
						</span>
					</div>
					<!-- Grid -->
					<div class="grid grid-cols-8 md:grid-cols-11 gap-1 w-full">
						{#each prog.bookGrid as entry (entry.bookId)}
							{@const bookMeta = bibleBooks.find(
								(b) => b.id === entry.bookId,
							)}
							<div
								class="aspect-square flex items-center justify-center rounded text-[9px] md:text-[10px] font-bold cursor-default {bookTileClass(
									entry.tier,
								)}"
								title="{bookMeta?.name ??
									entry.bookId} — {entry.tier}{entry.avgGuesses !==
								null
									? ` (avg ${entry.avgGuesses})`
									: ''}"
							>
								{entry.bookId}
							</div>
						{/each}
					</div>
					<p class="text-xs text-gray-500 mt-3 leading-relaxed">
						<span class="text-blue-400 font-medium">Explored</span>
						— played at least once<br />
						<span class="text-purple-400 font-medium"
							>Mastered</span
						>
						— avg &le; 3 guesses over 2+ plays<br />
						<span class="text-emerald-400 font-medium">Perfect</span> —
						mastered and guessed in 1 at least once
					</p>
				</Container>
			</div>

			<!-- Activity Calendar -->
			<div class="mb-6">
				<ActivityCalendar completions={prog.completions} />
			</div>

			<!-- Skill Growth Chart (hidden, needs rework) -->
			{#if false && showChart}
				<div class="mb-6">
					<Container class="p-4 md:p-6 w-full">
						<div class="w-full">
							<div class="flex items-baseline gap-2 mb-1">
								<h2 class="text-xl font-bold text-gray-100">
									Skill Growth
								</h2>
								<span class="text-xs text-gray-400">
									Lower is better
								</span>
							</div>
							<svg
								viewBox="0 0 400 135"
								class="w-full"
								aria-hidden="true"
							>
								<defs>
									<linearGradient
										id="chartFill"
										x1="0"
										y1="0"
										x2="0"
										y2="1"
									>
										<stop
											offset="0%"
											stop-color="#10b981"
											stop-opacity="0.3"
										/>
										<stop
											offset="100%"
											stop-color="#10b981"
											stop-opacity="0"
										/>
									</linearGradient>
								</defs>
								<!-- Y-axis label -->
								<text
									transform="translate(8, 60) rotate(-90)"
									text-anchor="middle"
									font-size="8"
									fill="#9ca3af"
								>Guesses</text>
								<!-- Fill polygon -->
								<polygon
									points="{polylinePoints} {svgX(
										chartPoints.length - 1,
										chartPoints.length,
									)},110 {svgX(0, chartPoints.length)},110"
									fill="url(#chartFill)"
								/>
								<!-- Line -->
								<polyline
									points={polylinePoints}
									fill="none"
									stroke="#10b981"
									stroke-width="2"
									stroke-linecap="round"
									stroke-linejoin="round"
								/>
								<!-- Dots -->
								{#each chartPoints as point, i (i)}
									<circle
										cx={svgX(i, chartPoints.length)}
										cy={svgY(point.avgGuesses, maxGuesses)}
										r="3"
										fill="#10b981"
									/>
									<text
										x={svgX(i, chartPoints.length)}
										y={svgY(point.avgGuesses, maxGuesses) - 6}
										font-size="7"
										fill="#6ee7b7"
										text-anchor="middle"
									>{point.avgGuesses}</text>
								{/each}
								<!-- X-axis labels -->
								<text
									x={svgX(0, chartPoints.length)}
									y="118"
									font-size="8"
									fill="#9ca3af"
									text-anchor="middle"
								>
									{chartPoints[0].label}
								</text>
								<text
									x={svgX(
										chartPoints.length - 1,
										chartPoints.length,
									)}
									y="118"
									font-size="8"
									fill="#9ca3af"
									text-anchor="middle"
								>
									{chartPoints[chartPoints.length - 1].label}
								</text>
								<!-- X-axis title -->
								<text
									x="200"
									y="132"
									font-size="8"
									fill="#9ca3af"
									text-anchor="middle"
								>Date</text>
							</svg>
							{#if chartImproving}
								<p class="text-xs text-emerald-400 mt-1">
									You're getting better!
								</p>
							{/if}
							<p
								class="text-xs text-gray-500 mt-2 leading-relaxed"
							>
								Each point is your average guesses over a
								rolling window of games. A downward trend means
								you're improving.
							</p>
						</div>
					</Container>
				</div>
			{/if}

			<!-- Achievements -->
			{#if prog.milestones.length > 0}
				<div class="mb-6">
					<h2 class="text-xl font-bold text-gray-100 mb-3">🏆 Achievements</h2>
					<div class="grid grid-cols-3 md:grid-cols-4 gap-2 md:gap-3">
						{#each prog.milestones.filter(m => m.achieved) as milestone (milestone.id)}
							<Container class="p-3 min-h-[130px]">
								<div class="text-center flex flex-col items-center justify-center h-full">
									<div class="text-2xl mb-1">{milestone.emoji}</div>
									<div class="text-sm font-bold text-yellow-300 leading-tight mb-1">
										{milestone.name}
									</div>
									<div class="text-xs text-gray-400 leading-tight">
										{milestone.description}
									</div>
									{#if milestone.achievedDate}
										<div class="text-[10px] text-gray-500 mt-1">
											{formatDate(milestone.achievedDate)}
										</div>
									{:else}
										<div class="text-[10px] text-emerald-500 mt-1">Earned</div>
									{/if}
								</div>
							</Container>
						{/each}
					</div>
					<p class="text-xs text-gray-500 mt-2">{prog.milestones.filter(m => m.achieved).length} / {prog.milestones.length} achievements unlocked</p>
				</div>
			{/if}

			<!-- Insights -->
			{#if showInsights}
				<div class="mb-6">
					<h2 class="text-xl font-bold text-gray-100 mb-3">
						Insights
					</h2>
					<div class="flex flex-col gap-3">
						{#if prog.testamentStats.old && prog.testamentStats.new}
							{@const comparison = testamentComparison(
								prog.testamentStats.old,
								prog.testamentStats.new,
							)}
							{#if comparison}
								<Container class="p-4 w-full">
									<div class="flex items-start gap-3 w-full">
										<span class="text-2xl">📊</span>
										<div class="flex-1 min-w-0">
											<p
												class="text-gray-100 font-medium text-sm"
											>
												{comparison}
											</p>
											<p
												class="text-gray-400 text-xs mt-0.5"
											>
												OT avg: {prog.testamentStats.old
													.avgGuesses} guesses &bull; NT
												avg: {prog.testamentStats.new
													.avgGuesses} guesses
											</p>
										</div>
									</div>
								</Container>
							{/if}
						{/if}

						{#if bestSection && bestSection.count >= 3}
							<Container class="p-4 w-full">
								<div class="flex items-start gap-3 w-full">
									<span class="text-2xl">🌟</span>
									<div class="flex-1 min-w-0">
										<p
											class="text-gray-100 font-medium text-sm"
										>
											Your strongest section: {bestSection.section}
										</p>
										<p class="text-gray-400 text-xs mt-0.5">
											{bestSection.avgGuesses} avg guesses
											across {bestSection.count} games
										</p>
									</div>
								</div>
							</Container>
						{/if}

						{#if hardestSection}
							{@const hard = hardestSection}
							{#if hard && hard.count >= 3}
								<Container class="p-4 w-full">
									<div class="flex items-start gap-3 w-full">
										<span class="text-2xl">💪</span>
										<div class="flex-1 min-w-0">
											<p
												class="text-gray-100 font-medium text-sm"
											>
												Room to grow: {hard.section}
											</p>
											<p
												class="text-gray-400 text-xs mt-0.5"
											>
												{hard.avgGuesses} avg guesses across
												{hard.count} games
											</p>
										</div>
									</div>
								</Container>
							{/if}
						{/if}
					</div>
				</div>
			{/if}
		{/if}
	</div>
</div>

<AuthModal bind:isOpen={authModalOpen} {anonymousId} />
