import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { getSurrealDB } from '$lib/server/db';

/**
 * POST /api/campaigns/[id]/check-availability
 * 
 * Vérifie la disponibilité des écrans sélectionnés pour une campagne
 * SANS les verrouiller. Supprime les écrans indisponibles de la campagne en DB.
 * 
 * Ne signale que les écrans indisponibles sur TOUTE la période (réservés par un autre).
 * Les semaines indisponibles individuelles sont déjà gérées côté UI.
 * 
 * Body: { screen_ids: string[], start_date: string, end_date: string, week_numbers: number[] }
 */
export const POST: RequestHandler = async ({ locals, params, request }) => {
	if (!locals.user) {
		return json({ error: 'Non autorisé' }, { status: 401 });
	}

	const userId = String(locals.user.id).replace('user:', '');
	const campaignId = String(params.id);

	try {
		const body = await request.json();
		const { screen_ids, start_date, end_date, week_numbers } = body;

		if (!screen_ids || !Array.isArray(screen_ids) || screen_ids.length === 0) {
			return json({ error: 'screen_ids requis' }, { status: 400 });
		}

		if (!start_date || !end_date) {
			return json({ error: 'start_date et end_date requis' }, { status: 400 });
		}

		if (!week_numbers || !Array.isArray(week_numbers) || week_numbers.length === 0) {
			return json({ error: 'week_numbers requis' }, { status: 400 });
		}

		const db = await getSurrealDB();

		// Clean screen IDs (strip prefix if present)
		const cleanScreenIds = screen_ids.map((id: any) => String(id).replace('screen:', ''));

		// Verify the campaign belongs to the user
		const campaigns = await db.query<any[]>(
			`SELECT id FROM campaign WHERE id = type::thing("campaign", $campaignId) AND user = type::thing("user", $userId)`,
			{ campaignId, userId }
		);

		const campaignResult = Array.isArray(campaigns) ? (Array.isArray(campaigns[0]) ? campaigns[0] : campaigns) : [];
		if (!campaignResult || campaignResult.length === 0) {
			return json({ error: 'Campagne non trouvée' }, { status: 404 });
		}

		const removedScreens: { id: string; name: string; reason: string }[] = [];
		const availableScreenIds: string[] = [];

		// Batch query: get all screens info at once
		const screenThings = cleanScreenIds.map((id: string) => `type::thing("screen", "${id}")`).join(', ');
		const screenInfoResult = await db.query<any[]>(
			`SELECT id, name FROM screen WHERE id IN [${screenThings}]`
		);
		const allScreens = Array.isArray(screenInfoResult[0]) ? screenInfoResult[0] : (Array.isArray(screenInfoResult) ? screenInfoResult : []);
		const screenMap = new Map<string, string>();
		for (const s of allScreens) {
			const sid = typeof s.id === 'string' ? s.id.replace('screen:', '') : s.id?.id || String(s.id);
			screenMap.set(sid, s.name || `Ecran ${sid}`);
		}

		// Batch query: get all conflicting bookings at once
		const bookingsResult = await db.query<any[]>(
			`SELECT screen, campaign, start_date, end_date, selected_weeks 
			 FROM screen_booking 
			 WHERE screen IN [${screenThings}]
			 AND campaign != type::thing("campaign", $campaignId)
			 AND status IN ['active', 'confirmed', 'locked']
			 AND (start_date <= $endDate AND end_date >= $startDate)`,
			{ campaignId, startDate: start_date, endDate: end_date }
		);
		const allBookings = Array.isArray(bookingsResult[0]) ? bookingsResult[0] : (Array.isArray(bookingsResult) ? bookingsResult : []);

		// Group bookings by screen
		const bookingsByScreen = new Map<string, any[]>();
		for (const b of allBookings) {
			const bScreen = typeof b.screen === 'string' ? b.screen.replace('screen:', '') : b.screen?.id || String(b.screen);
			if (!bookingsByScreen.has(bScreen)) bookingsByScreen.set(bScreen, []);
			bookingsByScreen.get(bScreen)!.push(b);
		}

		// Check each screen
		for (const screenId of cleanScreenIds) {
			if (!screenMap.has(screenId)) {
				removedScreens.push({ id: screenId, name: `Ecran ${screenId}`, reason: 'Ecran introuvable' });
				continue;
			}

			const screenName = screenMap.get(screenId)!;
			const conflictingBookings = bookingsByScreen.get(screenId) || [];

			let conflictingWeeksCount = 0;
			if (conflictingBookings.length > 0) {
				const bookedWeeks = new Set<number>();
				for (const booking of conflictingBookings) {
					if (booking.selected_weeks && Array.isArray(booking.selected_weeks)) {
						for (const w of booking.selected_weeks) {
							if (week_numbers.includes(w)) bookedWeeks.add(w);
						}
					} else {
						conflictingWeeksCount = week_numbers.length;
						break;
					}
				}
				if (conflictingWeeksCount === 0) conflictingWeeksCount = bookedWeeks.size;
			}

			if (conflictingWeeksCount >= week_numbers.length) {
				removedScreens.push({ id: screenId, name: screenName, reason: 'Reserve par un autre annonceur' });
			} else {
				availableScreenIds.push(screenId);
			}
		}

		// Persist removal: batch delete screen_booking entries for unavailable screens
		if (removedScreens.length > 0) {
			try {
				const dbForDelete = await getSurrealDB();
				const removedThings = removedScreens.map(r => `type::thing("screen", "${r.id}")`).join(', ');
				await dbForDelete.query(
					`DELETE FROM screen_booking 
					 WHERE screen IN [${removedThings}] 
					 AND campaign = type::thing("campaign", $campaignId)`,
					{ campaignId }
				);
			} catch (e) {
				console.error('Failed to delete bookings for removed screens:', e);
			}
		}

		return json({
			removed_screens: removedScreens,
			available_screens: availableScreenIds,
			total_checked: screen_ids.length,
			total_available: availableScreenIds.length,
		});
	} catch (error) {
		console.error('Error checking screen availability:', error);
		console.error('Debug info:', { userId, campaignId, body: 'see above' });
		const message = error instanceof Error ? error.message : 'Erreur serveur';
		return json({ error: message }, { status: 500 });
	}
};
