import { db } from '$lib/server/db';
import { dailyCompletions, type DailyCompletion } from '$lib/server/db/schema';
import { eq, desc } from 'drizzle-orm';
import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ url, locals }) => {
	// Check if user is authenticated
	if (!locals.user) {
		return {
			stats: null,
			error: null,
			user: null,
			session: null,
			requiresAuth: true
		};
	}
	
	const userId = locals.user.id;
	
	if (!userId) {
		return {
			stats: null,
			error: 'No user ID provided',
			user: locals.user,
			session: locals.session
		};
	}

	try {
		// Get all completions for this user
		const completions = await db
			.select()
			.from(dailyCompletions)
			.where(eq(dailyCompletions.anonymousId, userId))
			.orderBy(desc(dailyCompletions.date));

		if (completions.length === 0) {
			return {
				stats: {
					totalSolves: 0,
					avgGuesses: 0,
					gradeDistribution: {
						'S++': 0,
						'S+': 0,
						'A+': 0,
						'A': 0,
						'B+': 0,
						'B': 0,
						'C+': 0,
						'C': 0
					},
					currentStreak: 0,
					bestStreak: 0,
					recentCompletions: []
				},
				user: locals.user,
				session: locals.session
			};
		}

		// Calculate basic stats
		const totalSolves = completions.length;
		const totalGuesses = completions.reduce((sum: number, c: DailyCompletion) => sum + c.guessCount, 0);
		const avgGuesses = Math.round((totalGuesses / totalSolves) * 100) / 100;

		// Calculate grade distribution
		const gradeDistribution = {
			'S++': 0, // This will be calculated differently since we don't store chapter correctness
			'S+': completions.filter((c: DailyCompletion) => c.guessCount === 1).length,
			'A+': completions.filter((c: DailyCompletion) => c.guessCount === 2).length,
			'A': completions.filter((c: DailyCompletion) => c.guessCount === 3).length,
			'B+': completions.filter((c: DailyCompletion) => c.guessCount >= 4 && c.guessCount <= 6).length,
			'B': completions.filter((c: DailyCompletion) => c.guessCount >= 7 && c.guessCount <= 10).length,
			'C+': completions.filter((c: DailyCompletion) => c.guessCount >= 11 && c.guessCount <= 15).length,
			'C': completions.filter((c: DailyCompletion) => c.guessCount > 15).length
		};

		// Calculate streaks
		const sortedDates = completions
			.map((c: DailyCompletion) => c.date)
			.sort();
		
		let currentStreak = 0;
		let bestStreak = 0;
		let tempStreak = 1;
		
		if (sortedDates.length > 0) {
			// Check if current streak is active (includes today or yesterday)
			const today = new Date().toISOString().split('T')[0];
			const yesterday = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString().split('T')[0];
			const lastPlayedDate = sortedDates[sortedDates.length - 1];
			
			if (lastPlayedDate === today || lastPlayedDate === yesterday) {
				currentStreak = 1;
				
				// Count backwards from the most recent date
				for (let i = sortedDates.length - 2; i >= 0; i--) {
					const currentDate = new Date(sortedDates[i + 1]);
					const prevDate = new Date(sortedDates[i]);
					const daysDiff = Math.floor((currentDate.getTime() - prevDate.getTime()) / (1000 * 60 * 60 * 24));
					
					if (daysDiff === 1) {
						currentStreak++;
					} else {
						break;
					}
				}
			}
			
			// Calculate best streak
			bestStreak = 1;
			for (let i = 1; i < sortedDates.length; i++) {
				const currentDate = new Date(sortedDates[i]);
				const prevDate = new Date(sortedDates[i - 1]);
				const daysDiff = Math.floor((currentDate.getTime() - prevDate.getTime()) / (1000 * 60 * 60 * 24));
				
				if (daysDiff === 1) {
					tempStreak++;
				} else {
					bestStreak = Math.max(bestStreak, tempStreak);
					tempStreak = 1;
				}
			}
			bestStreak = Math.max(bestStreak, tempStreak);
		}

		// Get recent completions (last 7 days)
		const recentCompletions = completions
			.slice(0, 7)
			.map((c: DailyCompletion) => ({
				date: c.date,
				guessCount: c.guessCount,
				grade: getGradeFromGuesses(c.guessCount)
			}));

		return {
			stats: {
				totalSolves,
				avgGuesses,
				gradeDistribution,
				currentStreak,
				bestStreak,
				recentCompletions
			},
			user: locals.user,
			session: locals.session
		};

	} catch (error) {
		console.error('Error fetching user stats:', error);
		return {
			stats: null,
			error: 'Failed to fetch stats',
			user: locals.user,
			session: locals.session
		};
	}
};

function getGradeFromGuesses(guessCount: number): string {
	if (guessCount === 1) return "S+";
	if (guessCount === 2) return "A+";
	if (guessCount === 3) return "A";
	if (guessCount >= 4 && guessCount <= 6) return "B+";
	if (guessCount >= 7 && guessCount <= 10) return "B";
	if (guessCount >= 11 && guessCount <= 15) return "C+";
	return "C";
}