import { error } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import { db } from '$lib/server/db';
import { find, findMedia, user } from '$lib/server/db/schema';
import { eq, and, sql, desc } from 'drizzle-orm';
import { getSignedR2Url } from '$lib/server/r2';

export const load: PageServerLoad = async ({ locals, url }) => {
	if (!locals.user) {
		throw error(401, 'Authentication required');
	}

	// Get query parameters for location-based filtering
	const lat = url.searchParams.get('lat');
	const lng = url.searchParams.get('lng');
	const radius = url.searchParams.get('radius') || '50'; // Default 50km radius

	try {
		// Build where conditions
		const baseCondition = sql`(${find.isPublic} = 1 OR ${find.userId} = ${locals.user.id})`;
		let whereConditions = baseCondition;

		// Add location filtering if coordinates provided
		if (lat && lng) {
			const radiusKm = parseFloat(radius);
			// Simple bounding box query for MVP (can upgrade to proper distance calculation later)
			const latOffset = radiusKm / 111; // Approximate degrees per km for latitude
			const lngOffset = radiusKm / (111 * Math.cos((parseFloat(lat) * Math.PI) / 180));

			const locationConditions = and(
				baseCondition,
				sql`${find.latitude} BETWEEN ${parseFloat(lat) - latOffset} AND ${
					parseFloat(lat) + latOffset
				}`,
				sql`${find.longitude} BETWEEN ${parseFloat(lng) - lngOffset} AND ${
					parseFloat(lng) + lngOffset
				}`
			);

			if (locationConditions) {
				whereConditions = locationConditions;
			}
		}

		// Get all finds with filtering
		const finds = await db
			.select({
				id: find.id,
				title: find.title,
				description: find.description,
				latitude: find.latitude,
				longitude: find.longitude,
				locationName: find.locationName,
				category: find.category,
				isPublic: find.isPublic,
				createdAt: find.createdAt,
				userId: find.userId,
				username: user.username
			})
			.from(find)
			.innerJoin(user, eq(find.userId, user.id))
			.where(whereConditions)
			.orderBy(desc(find.createdAt))
			.limit(100);

		// Get media for all finds
		const findIds = finds.map((f) => f.id);
		let media: Array<{
			id: string;
			findId: string;
			type: string;
			url: string;
			thumbnailUrl: string | null;
			orderIndex: number | null;
		}> = [];

		if (findIds.length > 0) {
			media = await db
				.select({
					id: findMedia.id,
					findId: findMedia.findId,
					type: findMedia.type,
					url: findMedia.url,
					thumbnailUrl: findMedia.thumbnailUrl,
					orderIndex: findMedia.orderIndex
				})
				.from(findMedia)
				.where(
					sql`${findMedia.findId} IN (${sql.join(
						findIds.map((id) => sql`${id}`),
						sql`, `
					)})`
				)
				.orderBy(findMedia.orderIndex);
		}

		// Group media by find
		const mediaByFind = media.reduce(
			(acc, item) => {
				if (!acc[item.findId]) {
					acc[item.findId] = [];
				}
				acc[item.findId].push(item);
				return acc;
			},
			{} as Record<string, typeof media>
		);

		// Combine finds with their media and generate signed URLs
		const findsWithMedia = await Promise.all(
			finds.map(async (findItem) => {
				const findMedia = mediaByFind[findItem.id] || [];

				// Generate signed URLs for all media items
				const mediaWithSignedUrls = await Promise.all(
					findMedia.map(async (mediaItem) => {
						// Extract path from URL if it's still a full URL, otherwise use as-is
						const path = mediaItem.url.startsWith('https://')
							? mediaItem.url.split('/').slice(3).join('/')
							: mediaItem.url;

						const thumbnailPath = mediaItem.thumbnailUrl?.startsWith('https://')
							? mediaItem.thumbnailUrl.split('/').slice(3).join('/')
							: mediaItem.thumbnailUrl;

						const [signedUrl, signedThumbnailUrl] = await Promise.all([
							getSignedR2Url(path, 24 * 60 * 60), // 24 hours
							thumbnailPath ? getSignedR2Url(thumbnailPath, 24 * 60 * 60) : Promise.resolve(null)
						]);

						return {
							...mediaItem,
							url: signedUrl,
							thumbnailUrl: signedThumbnailUrl
						};
					})
				);

				return {
					...findItem,
					media: mediaWithSignedUrls
				};
			})
		);

		return {
			finds: findsWithMedia
		};
	} catch (err) {
		console.error('Error loading finds:', err);
		return {
			finds: []
		};
	}
};
