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

/**
 * POST /api/campaigns/[id]/lock
 * 
 * Vérifie la disponibilité des écrans sélectionnés pour une campagne
 * et les verrouille pendant 1 heure.
 * 
 * Body: { screen_ids: string[], start_date: string, end_date: string, week_numbers: number[] }
 * 
 * Returns:
 * - removed_screens: écrans qui ne sont plus disponibles
 * - locked_until: date d'expiration du verrouillage
 */
export const POST: RequestHandler = async ({ locals, params, request }) => {
	if (!locals.user) {
		return json({ error: 'Non autorisé' }, { status: 401 });
	}

	const userId = locals.user.id.replace('user:', '');
	const campaignId = 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 });
		}

		const db = await getSurrealDB();

		// 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 }
		);

		if (!campaigns || campaigns.length === 0) {
			return json({ error: 'Campagne non trouvée' }, { status: 404 });
		}

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

		// Check availability for each screen
		for (const screenId of screen_ids) {
			try {
				// Get screen info
				const [screenResult] = await db.query<any[]>(
					`SELECT id, name, unavailable_weeks FROM screen WHERE id = type::thing("screen", $screenId)`,
					{ screenId }
				);
				const screen = screenResult?.[0];
				if (!screen) {
					removedScreens.push({
						id: screenId,
						name: `Écran ${screenId}`,
						reason: 'Écran introuvable'
					});
					continue;
				}

				const screenName = screen.name || `Écran ${screenId}`;

				// Check for conflicting bookings from OTHER campaigns
				const [conflictingBookings] = await db.query<any[]>(
					`SELECT id, campaign, start_date, end_date, selected_weeks 
					 FROM screen_booking 
					 WHERE screen = type::thing("screen", $screenId)
					 AND campaign != type::thing("campaign", $campaignId)
					 AND status IN ['active', 'confirmed', 'locked']
					 AND (
					   (start_date <= $endDate AND end_date >= $startDate)
					 )`,
					{ screenId, campaignId, startDate: start_date, endDate: end_date }
				);

				// Check if any conflicting booking overlaps our selected weeks
				let hasConflict = false;
				if (conflictingBookings && conflictingBookings.length > 0) {
					for (const booking of conflictingBookings) {
						if (booking.selected_weeks && Array.isArray(booking.selected_weeks)) {
							const conflictWeeks = booking.selected_weeks.filter((w: number) =>
								week_numbers.includes(w)
							);
							if (conflictWeeks.length > 0) {
								hasConflict = true;
								break;
							}
						} else {
							// Date range overlap means conflict
							hasConflict = true;
							break;
						}
					}
				}

				// Check unavailable weeks
				const unavailableWeeks = screen.unavailable_weeks || [];
				const unavailableConflict = week_numbers.some((wn: number) =>
					unavailableWeeks.includes(wn)
				);

				if (hasConflict) {
					removedScreens.push({
						id: screenId,
						name: screenName,
						reason: 'Déjà réservé'
					});
				} else if (unavailableConflict) {
					removedScreens.push({
						id: screenId,
						name: screenName,
						reason: 'Semaines indisponibles'
					});
				} else {
					lockedScreenIds.push(screenId);
				}
			} catch (err) {
				console.error(`Error checking screen ${screenId}:`, err);
				removedScreens.push({
					id: screenId,
					name: `Écran ${screenId}`,
					reason: 'Erreur de vérification'
				});
			}
		}

		// Lock the available screens (1 hour)
		const lockedUntil = new Date(Date.now() + 60 * 60 * 1000).toISOString();

		if (lockedScreenIds.length > 0) {
			// Update/create lock records for the campaign
			await db.query(
				`UPDATE type::thing("campaign", $campaignId) SET 
					locked_screens = $screenIds,
					lock_expires_at = $lockedUntil,
					lock_created_at = time::now()
				`,
				{
					campaignId,
					screenIds: lockedScreenIds,
					lockedUntil,
				}
			);

			// Create/update screen_booking entries with 'locked' status for new screens
			for (const screenId of lockedScreenIds) {
				// Check if a booking already exists for this campaign+screen
				const [existing] = await db.query<any[]>(
					`SELECT id FROM screen_booking 
					 WHERE screen = type::thing("screen", $screenId) 
					 AND campaign = type::thing("campaign", $campaignId)`,
					{ screenId, campaignId }
				);

				if (existing && existing.length > 0) {
					// Update existing booking lock
					await db.query(
						`UPDATE $bookingId SET 
							status = IF status = 'confirmed' THEN 'confirmed' ELSE 'locked' END,
							lock_expires_at = $lockedUntil`,
						{ bookingId: existing[0].id, lockedUntil }
					);
				} else {
					// Create new locked booking
					await db.query(
						`CREATE screen_booking SET
							screen = type::thing("screen", $screenId),
							campaign = type::thing("campaign", $campaignId),
							user = type::thing("user", $userId),
							start_date = $startDate,
							end_date = $endDate,
							selected_weeks = $weekNumbers,
							status = 'locked',
							lock_expires_at = $lockedUntil,
							created_at = time::now()`,
						{
							screenId,
							campaignId,
							userId,
							startDate: start_date,
							endDate: end_date,
							weekNumbers: week_numbers,
							lockedUntil,
						}
					);
				}
			}
		}

		// Remove bookings for screens that are no longer available
		for (const removed of removedScreens) {
			await db.query(
				`DELETE FROM screen_booking 
				 WHERE screen = type::thing("screen", $screenId) 
				 AND campaign = type::thing("campaign", $campaignId)`,
				{ screenId: removed.id, campaignId }
			);
		}

		return json({
			removed_screens: removedScreens,
			locked_screens: lockedScreenIds,
			locked_until: lockedScreenIds.length > 0 ? lockedUntil : null,
			total_checked: screen_ids.length,
			total_available: lockedScreenIds.length,
		});
	} catch (error) {
		console.error('Error locking screens:', error);
		return json({ error: 'Erreur serveur' }, { status: 500 });
	}
};

/**
 * DELETE /api/campaigns/[id]/lock
 * 
 * Annule la réservation des écrans pour une campagne.
 * Supprime les bookings avec status 'locked' et remet les champs lock de la campagne à null.
 */
export const DELETE: RequestHandler = async ({ locals, params }) => {
	if (!locals.user) {
		return json({ error: 'Non autorisé' }, { status: 401 });
	}

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

	try {
		const db = await getSurrealDB();

		// 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 }
		);

		if (!campaigns || campaigns.length === 0) {
			return json({ error: 'Campagne non trouvée' }, { status: 404 });
		}

		// Remove locked bookings (keep confirmed ones)
		await db.query(
			`DELETE FROM screen_booking 
			 WHERE campaign = type::thing("campaign", $campaignId) 
			 AND status = 'locked'`,
			{ campaignId }
		);

		// Clear lock fields on campaign
		await db.query(
			`UPDATE type::thing("campaign", $campaignId) SET 
				locked_screens = [],
				lock_expires_at = NONE,
				lock_created_at = NONE
			`,
			{ campaignId }
		);

		return json({ success: true });
	} catch (error) {
		console.error('Error unlocking screens:', error);
		return json({ error: 'Erreur serveur' }, { status: 500 });
	}
};
