<script lang="ts">
	import { onMount } from 'svelte';
	import { page } from '$app/state';
	
	// Import components
	import EventInformation from './components/EventInformation.svelte';
	import EmailTemplate from './components/EmailTemplate.svelte';
	import GoogleAuthentication from './components/GoogleAuthentication.svelte';
	import ParticipantsTable from './components/ParticipantsTable.svelte';
	import EmailSending from './components/EmailSending.svelte';
	import EmailResults from './components/EmailResults.svelte';
	import Statistics from './components/Statistics.svelte';
	import { toast } from '$lib/stores/toast.js';

	let { data } = $props();

	// Types
	interface Event {
		id: string;
		created_at: string;
		created_by: string;
		name: string;
		date: string;
		section_id: string;
		email_subject: string;
		email_body: string;
		sheet_id: string;
		name_column: number;
		surname_column: number;
		email_column: number;
		confirmation_column: number;
	}

	interface Participant {
		id: string;
		name: string;
		surname: string;
		email: string;
		scanned: boolean;
		email_sent: boolean;
	}

	// State management with Svelte 5 runes
	let event = $state<Event | null>(null);
	let participants = $state<Participant[]>([]);
	let loading = $state(true);
	let participantsLoading = $state(true);
	let syncingParticipants = $state(false);
	let sendingEmails = $state(false);
	let updatingEmail = $state(false);
	let emailProgress = $state({ sent: 0, total: 0 });
	let emailResults = $state<{success: boolean, results: any[], summary: any} | null>(null);

	// Get event ID from URL params
	let eventId = $derived(page.url.searchParams.get('id'));

	onMount(async () => {
		if (eventId) {
			await loadEvent();
			await loadParticipants();
		}
	});

	async function loadEvent() {
		loading = true;
		try {
			const { data: eventData, error: eventError } = await data.supabase
				.from('events')
				.select('*')
				.eq('id', eventId)
				.single();

			if (eventError) throw eventError;
			event = eventData;
		} catch (err) {
			console.error('Error loading event:', err);
			toast.error('Failed to load event');
		} finally {
			loading = false;
		}
	}

	async function loadParticipants() {
		participantsLoading = true;
		try {
			const { data: participantsData, error: participantsError } = await data.supabase
				.from('participants')
				.select('id, name, surname, email, scanned, email_sent')
				.eq('event', eventId)
				.order('scanned', { ascending: true })
				.order('email_sent', { ascending: true })
				.order('name', { ascending: true });

			if (participantsError) throw participantsError;
			participants = participantsData || [];
		} catch (err) {
			console.error('Error loading participants:', err);
			toast.error('Failed to load participants');
		} finally {
			participantsLoading = false;
		}
	}

	async function syncParticipants() {
		if (!event || !event.sheet_id) {
			toast.error('Cannot sync participants: No Google Sheet is connected to this event');
			return;
		}

		// Check if user has Google authentication
		const refreshToken = localStorage.getItem('google_refresh_token');
		if (!refreshToken) {
			toast.error('Please connect your Google account first to sync participants');
			return;
		}

		syncingParticipants = true;
		try {
			// Fetch sheet data
			const response = await fetch(`/private/api/google/sheets/${event.sheet_id}/data`, {
				method: 'GET',
				headers: {
					Authorization: `Bearer ${refreshToken}`
				}
			});

			if (!response.ok) {
				if (response.status === 401) {
					throw new Error('Google authentication expired. Please reconnect your Google account.');
				}
				throw new Error('Failed to fetch sheet data');
			}

			const sheetData = await response.json();
			const rows = sheetData.values || [];

			if (rows.length === 0) throw new Error('No data found in sheet');

			// Extract participant data based on column mapping
			const names: string[] = [];
			const surnames: string[] = [];
			const emails: string[] = [];

			// Skip header row (start from index 1)
			for (let i = 1; i < rows.length; i++) {
				const row = rows[i];
				if (row.length > 0) {
					const name = row[event.name_column - 1] || '';
					const surname = row[event.surname_column - 1] || '';
					const email = row[event.email_column - 1] || '';
					const confirmation = row[event.confirmation_column - 1] || '';

					// Only add if the row has meaningful data (not all empty) AND confirmation is TRUE
					const isConfirmed =
						confirmation.toString().toLowerCase() === 'true' ||
						confirmation.toString().toLowerCase() === 'yes' ||
						confirmation === '1' ||
						confirmation === 'x';

					if ((name.trim() || surname.trim() || email.trim()) && isConfirmed) {
						names.push(name.trim());
						surnames.push(surname.trim());
						emails.push(email.trim());
					}
				}
			}

			// Call database function to add participants
			const { error: syncError } = await data.supabase.rpc('participants_add_bulk', {
				p_event: eventId,
				p_names: names,
				p_surnames: surnames,
				p_emails: emails
			});

			if (syncError) throw syncError;

			// Reload participants
			await loadParticipants();
			
			// Show success message with count of synced participants
			const previousCount = participants.length;
			const newCount = names.length;
			const addedCount = Math.max(0, participants.length - previousCount);
			
			toast.success(
				`Successfully synced participants. ${newCount} entries processed, ${addedCount} new participants added.`,
				5000
			);
		} catch (err) {
			console.error('Error syncing participants:', err);
			toast.error(`Failed to sync participants: ${err instanceof Error ? err.message : 'Unknown error'}`);
		} finally {
			syncingParticipants = false;
		}
	}

	async function sendEmailsToUncontacted() {
		if (!event) return;

		// Check if user has Google authentication
		const refreshToken = localStorage.getItem('google_refresh_token');
		if (!refreshToken) {
			toast.add({
				message: 'Please connect your Google account first to send emails',
				type: 'error'
			});
			return;
		}

		const uncontactedParticipants = participants.filter(p => !p.email_sent);
		if (uncontactedParticipants.length === 0) {
			toast.add({
				message: 'No uncontacted participants found',
				type: 'warning'
			});
			return;
		}

		sendingEmails = true;
		emailProgress = { sent: 0, total: uncontactedParticipants.length };
		emailResults = null;

		try {
			// Send all emails in batch
			const response = await fetch('/private/api/google/gmail', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json'
				},
				body: JSON.stringify({
					participants: uncontactedParticipants,
					subject: event.email_subject,
					text: event.email_body,
					eventId: event.id,
					refreshToken: refreshToken
				})
			});
			
			if (response.ok) {
				const result = await response.json();
				emailProgress.sent = result.summary.success;
				emailResults = result;
				
				// Update participants state to reflect email_sent status
				participants = participants.map(p => {
					const emailedParticipant = result.results.find((r: any) => r.participant.id === p.id);
					if (emailedParticipant && emailedParticipant.success) {
						return { ...p, email_sent: true };
					}
					return p;
				});
			} else {
				const errorData = await response.json();
				toast.add({
					message: errorData.error || 'Failed to send emails',
					type: 'error'
				});
				console.error('Email sending failed:', errorData);
			}
		} catch (err) {
			console.error('Error sending emails:', err);
			toast.add({
				message: 'Failed to send emails to participants',
				type: 'error'
			});
		} finally {
			sendingEmails = false;
		}
	}

	// For Email Template updating
	async function handleEmailUpdate(eventId: string, subject: string, body: string) {
		updatingEmail = true;
		
		try {
			// Call the email_modify RPC function
			const { error } = await data.supabase.rpc('email_modify', {
				p_event_id: eventId,
				p_email_subject: subject,
				p_email_body: body
			});
			
			if (error) throw error;
			
			// Update the local event data on success
			if (event) {
				event.email_subject = subject;
				event.email_body = body;
			}
			
			toast.add({
				message: 'Email template updated successfully',
				type: 'success'
			});
			
		} catch (err) {
			console.error('Error updating email template:', err);
			toast.add({
				message: 'Failed to update email template',
				type: 'error'
			});
		} finally {
			updatingEmail = false;
		}
	}

	function handleGoogleAuthSuccess() {
		// Success handled by toast in the component
	}
	
	function handleGoogleAuthError(errorMsg: string) {
		toast.add({
			message: errorMsg,
			type: 'error'
		});
	}
</script>

<div class="mt-2 mb-4">
	<h1 class="text-center text-2xl font-bold">Event Overview</h1>
</div>

<EventInformation {event} {loading} />

<GoogleAuthentication 
	{loading} 
	onSuccess={handleGoogleAuthSuccess} 
	onError={handleGoogleAuthError} 
/>

<ParticipantsTable
{event}
{participants}
{loading}
participantsLoading={participantsLoading}
syncingParticipants={syncingParticipants}
onSyncParticipants={syncParticipants}
/>

<div class="mb-4 rounded-lg border border-gray-300 bg-white p-6">
	<h2 class="mb-4 text-xl font-semibold text-gray-900">Statistics</h2>
	<Statistics 
		loading={loading || participantsLoading}
		totalCount={participants.length}
		scannedCount={participants.filter(p => p.scanned).length}
		emailSentCount={participants.filter(p => p.email_sent).length}
		pendingCount={participants.filter(p => !p.email_sent).length}
	/>
</div>

<EmailTemplate 
	{event} 
	{loading}
	{updatingEmail}
	onUpdateEmail={handleEmailUpdate} 
/>

<EmailSending 
  {loading}
  {participants}
  {sendingEmails}
  {emailProgress}
  {event}
  onSendEmails={sendEmailsToUncontacted}
/>

{#if emailResults}
	<EmailResults {emailResults} />
{/if}
