import { json, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { db } from '$lib/server/db';
import { dailyCompletions } from '$lib/server/db/schema';
import { desc } from 'drizzle-orm';

export const GET: RequestHandler = async ({ url }) => {
	const streakParam = url.searchParams.get('streak');
	const localDate = url.searchParams.get('localDate');

	if (!streakParam || !localDate) {
		error(400, 'Missing streak or localDate');
	}

	const targetStreak = parseInt(streakParam, 10);
	if (isNaN(targetStreak) || targetStreak < 1) {
		error(400, 'Invalid streak');
	}

	// Fetch all completions ordered by anonymous_id and date desc
	// so we can walk each user's history to compute their current streak.
	const rows = await db
		.select({
			anonymousId: dailyCompletions.anonymousId,
			date: dailyCompletions.date,
		})
		.from(dailyCompletions)
		.orderBy(desc(dailyCompletions.date));

	// Group dates by user
	const byUser = new Map<string, string[]>();
	for (const row of rows) {
		const list = byUser.get(row.anonymousId);
		if (list) {
			list.push(row.date);
		} else {
			byUser.set(row.anonymousId, [row.date]);
		}
	}

	// Calculate the current streak for each user.
	// Start from today; if the user hasn't played today yet, try yesterday so
	// that streaks aren't zeroed out mid-day before the player has had a chance
	// to complete today's puzzle.
	const yesterday = new Date(`${localDate}T00:00:00`);
	yesterday.setDate(yesterday.getDate() - 1);
	const yesterdayStr = yesterday.toLocaleDateString('en-CA');

	const thirtyDaysAgo = new Date(`${localDate}T00:00:00`);
	thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
	const thirtyDaysAgoStr = thirtyDaysAgo.toLocaleDateString('en-CA');

	// For each user, compute their current streak and whether they've played
	// within the last 30 days. "Eligible players" = active streak OR recent play.
	const userStats: { streak: number; isEligible: boolean }[] = [];
	for (const [, dates] of byUser) {
		// dates are already desc-sorted
		const dateSet = new Set(dates);

		// Pick the most recent anchor: today if played, otherwise yesterday
		const anchor = dateSet.has(localDate) ? localDate : yesterdayStr;

		let streak = 0;
		let cursor = new Date(`${anchor}T00:00:00`);

		while (true) {
			const dateStr = cursor.toLocaleDateString('en-CA');
			if (!dateSet.has(dateStr)) break;
			streak++;
			cursor.setDate(cursor.getDate() - 1);
		}

		const hasRecentPlay = dates.some((d) => d >= thirtyDaysAgoStr);
		userStats.push({ streak, isEligible: streak >= 1 || hasRecentPlay });
	}

	const eligiblePlayers = userStats.filter((u) => u.isEligible);

	if (eligiblePlayers.length === 0) {
		console.log('[streak-percentile] No eligible players found, returning 100th percentile');
		return json({ percentile: 100 });
	}

	// Percentage of eligible players who have a streak >= targetStreak
	const atOrAbove = eligiblePlayers.filter((u) => u.streak >= targetStreak).length;
	const raw = (atOrAbove / eligiblePlayers.length) * 100;
	const percentile = raw < 1 ? Math.round(raw * 100) / 100 : Math.round(raw);

	console.log('[streak-percentile]', {
		localDate,
		targetStreak,
		totalUsers: byUser.size,
		totalRows: rows.length,
		eligiblePlayers: eligiblePlayers.length,
		activeStreaks: userStats.filter((u) => u.streak >= 1).length,
		recentPlayers: userStats.filter((u) => u.isEligible).length,
		atOrAbove,
		raw,
		percentile,
	});

	return json({ percentile });
};
