import { json, error } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { generateAltText, type RecipeContext } from '$lib/server/ai/alttext.js';
import { checkOllamaHealth } from '$lib/server/ai/ollama.js';
import { Recipe } from '$models/Recipe.js';

export const POST: RequestHandler = async ({ request, locals }) => {
	// Check authentication
	const session = await locals.auth();
	if (!session?.user) {
		throw error(401, 'Unauthorized');
	}

	try {
		const body = await request.json();
		const { filter = 'missing', limit = 10, modelName } = body;

		// Check if Ollama is available
		const isOllamaAvailable = await checkOllamaHealth();
		if (!isOllamaAvailable) {
			throw error(503, 'Ollama service is not available. Make sure Ollama is running.');
		}

		// Build query based on filter
		let query: Record<string, unknown> = { images: { $exists: true, $ne: [] } };

		if (filter === 'missing') {
			// Find recipes with images but missing alt text
			query = {
				images: {
					$elemMatch: {
						mediapath: { $exists: true },
						$or: [{ alt: { $exists: false } }, { alt: '' }],
					},
				},
			};
		} else if (filter === 'all') {
			// Process all recipes with images
			query = { images: { $exists: true, $ne: [] } };
		}

		// Fetch recipes
		const recipes = await Recipe.find(query).limit(limit);

		if (recipes.length === 0) {
			return json({
				success: true,
				processed: 0,
				message: 'No recipes found matching criteria',
			});
		}

		const results: Array<{
			shortName: string;
			name: string;
			processed: number;
			failed: number;
		}> = [];

		// Process each recipe
		for (const recipe of recipes) {
			let processed = 0;
			let failed = 0;
			if (!recipe.images) continue;

			for (let i = 0; i < recipe.images.length; i++) {
				const image = recipe.images[i];

				// Skip if alt text exists and we're only processing missing ones
				if (filter === 'missing' && image.alt) {
					continue;
				}

				try {
					// Prepare context
					const context: RecipeContext = {
						name: recipe.name,
						category: recipe.category,
						tags: recipe.tags,
					};

					// Generate alt text
					const altTextResult = await generateAltText(
						image.mediapath,
						context,
						modelName || 'gemma3:latest'
					);

					// Update German alt text
					recipe.images[i].alt = altTextResult.de;

					// Ensure translations.en.images array exists
					if (!recipe.translations) {
						(recipe as any).translations = { en: { images: [] } };
					}
					if (!recipe.translations!.en) {
						(recipe.translations as any).en = { images: [] };
					}
					if (!recipe.translations!.en!.images) {
						(recipe.translations!.en as any).images = [];
					}

					// Ensure array has enough entries
					while (recipe.translations!.en!.images!.length <= i) {
						recipe.translations!.en!.images!.push({ alt: '', caption: '' } as any);
					}

					// Update English alt text
					recipe.translations!.en!.images![i].alt = altTextResult.en;

					processed++;
				} catch (err) {
					console.error(`Failed to process image ${i} for recipe ${recipe.short_name}:`, err);
					failed++;
				}
			}

			// Save recipe if any images were processed
			if (processed > 0) {
				await recipe.save();
			}

			results.push({
				shortName: recipe.short_name,
				name: recipe.name,
				processed,
				failed,
			});
		}

		return json({
			success: true,
			processed: results.reduce((sum, r) => sum + r.processed, 0),
			failed: results.reduce((sum, r) => sum + r.failed, 0),
			results,
		});
	} catch (err) {
		console.error('Error in bulk alt text generation:', err);

		if (err instanceof Error && 'status' in err) {
			throw err;
		}

		throw error(500, err instanceof Error ? err.message : 'Failed to generate alt text');
	}
};

/**
 * GET endpoint to check status and get stats
 */
export const GET: RequestHandler = async ({ locals }) => {
	// Check authentication
	const session = await locals.auth();
	if (!session?.user) {
		throw error(401, 'Unauthorized');
	}

	try {
		// Count recipes with missing alt text
		const totalWithImages = await Recipe.countDocuments({
			images: { $exists: true, $ne: [] },
		});

		const missingAltText = await Recipe.countDocuments({
			images: {
				$elemMatch: {
					mediapath: { $exists: true },
					$or: [{ alt: { $exists: false } }, { alt: '' }],
				},
			},
		});

		// Check Ollama health
		const ollamaAvailable = await checkOllamaHealth();

		return json({
			totalWithImages,
			missingAltText,
			ollamaAvailable,
		});
	} catch (err) {
		throw error(500, 'Failed to fetch statistics');
	}
};
