<script lang="ts">
	import { onMount } from 'svelte';
	import { isTokenValid, getUserInfo, revokeToken } from '$lib/google/auth/client.js';
	import type { GoogleSheet } from '$lib/google/sheets/types.ts';
	import { goto } from '$app/navigation';
	
	// Import Components
	import GoogleAuthStep from './components/GoogleAuthStep.svelte';
	import EventDetailsStep from './components/EventDetailsStep.svelte';
	import GoogleSheetsStep from './components/GoogleSheetsStep.svelte';
	import EmailSettingsStep from './components/EmailSettingsStep.svelte';
	import StepNavigator from './components/StepNavigator.svelte';
	import StepNavigation from './components/StepNavigation.svelte';

	let { data } = $props();

	// Step management
	let currentStep = $state(0); // Start at step 0 for Google auth check
	const totalSteps = 4; // Increased to include auth step

	// Step 0: Google Auth
	let authData = $state({
		isConnected: false,
		checking: true,
		connecting: false,
		showCancelOption: false,
		token: null as string | null,
		error: null as string | null,
		userEmail: null as string | null
	});

	// Step 1: Event Details
	let eventData = $state({
		name: '',
		date: ''
	});

	// Step 2: Google Sheets
	let sheetsData = $state({
		availableSheets: [] as GoogleSheet[],
		selectedSheet: null as GoogleSheet | null,
		sheetData: [] as string[][],
		columnMapping: {
			name: 0,  // Initialize to 0 (no column selected)
			surname: 0,
			email: 0,
			confirmation: 0
		},
		loading: false,
		expandedSheetList: true // Add this flag to control sheet list expansion
	});

	// Step 3: Email
	let emailData = $state({
		subject: '',
		body: ''
	});

	// General state
	let loading = $state(false);
	let errors = $state<Record<string, string>>({});

	onMount(async () => {
		// Check Google auth status on mount
		await checkGoogleAuth();
		
		if (currentStep === 2) {
			await loadRecentSheets();
		}
	});

	// Google Auth functions
	async function checkGoogleAuth() {
		authData.checking = true;
		try {
			const accessToken = localStorage.getItem('google_access_token');
			const refreshToken = localStorage.getItem('google_refresh_token');
			
			if (accessToken && refreshToken) {
				// Check if token is still valid
				const isValid = await isTokenValid(accessToken);
				authData.isConnected = isValid;
				authData.token = accessToken;
				
				if (isValid) {
					// Fetch user info
					await fetchUserInfo(accessToken);
				}
			} else {
				authData.isConnected = false;
				authData.userEmail = null;
			}
		} catch (error) {
			console.error('Error checking Google auth:', error);
			authData.isConnected = false;
			authData.error = 'Error checking Google connection';
			authData.userEmail = null;
		} finally {
			authData.checking = false;
		}
	}

	async function connectToGoogle() {
		authData.error = '';
		authData.connecting = true;
		
		try {
			// Open popup window for OAuth
			const popup = window.open(
				'/auth/google',
				'google-auth',
				'width=500,height=600,scrollbars=yes,resizable=yes,left=' + 
				Math.round(window.screen.width / 2 - 250) + ',top=' + 
				Math.round(window.screen.height / 2 - 300)
			);

			if (!popup) {
				authData.error = 'Failed to open popup window. Please allow popups for this site.';
				authData.connecting = false;
				return;
			}

			let authCompleted = false;
			let popupTimer: number | null = null;
			let cancelTimeout: number | null = null;

			// Store current timestamp to detect changes in localStorage
			const startTimestamp = localStorage.getItem('google_auth_timestamp') || '0';
			
			// Poll localStorage for auth completion
			const pollInterval = setInterval(() => {
				try {
					const currentTimestamp = localStorage.getItem('google_auth_timestamp');
					
					// If timestamp has changed, auth is complete
					if (currentTimestamp && currentTimestamp !== startTimestamp) {
						handleAuthSuccess();
					}
				} catch (e) {
					console.error('Error checking auth timestamp:', e);
				}
			}, 500); // Poll every 500ms
			
			// Common handler for authentication success
			function handleAuthSuccess() {
				if (authCompleted) return; // Prevent duplicate handling
				
				authCompleted = true;
				authData.connecting = false;
				authData.showCancelOption = false;
				
				// Clean up timers
				clearInterval(pollInterval);
				if (popupTimer) clearTimeout(popupTimer);
				if (cancelTimeout) clearTimeout(cancelTimeout);
				
				// Update auth state
				setTimeout(checkGoogleAuth, 100);
			}
			
			// Clean up function to handle all cleanup in one place
			const cleanUp = () => {
				clearInterval(pollInterval);
				if (popupTimer) clearTimeout(popupTimer);
				if (cancelTimeout) clearTimeout(cancelTimeout);
				authData.connecting = false;
			};

			// Set a timeout for initial auth check
			popupTimer = setTimeout(() => {
				// Only check if auth isn't already completed
				if (!authCompleted) {
					cleanUp();
					// Check if tokens were stored by the popup before it was closed
					setTimeout(checkGoogleAuth, 100);
				}
			}, 30 * 1000) as unknown as number; // Reduced from 60s to 30s

			// Show cancel option sooner
			cancelTimeout = setTimeout(() => {
				if (!authCompleted) {
					authData.showCancelOption = true;
				}
			}, 10 * 1000) as unknown as number; // Reduced from 20s to 10s

			// Final cleanup timeout
			setTimeout(() => {
				if (!authCompleted) {
					cleanUp();
				}
			}, 60 * 1000); // Reduced from 3min to 1min

		} catch (error) {
			console.error('Error connecting to Google:', error);
			authData.error = 'Failed to connect to Google';
			authData.connecting = false;
		}
	}
	
	function cancelGoogleAuth() {
		authData.connecting = false;
		authData.showCancelOption = false;
	}
	
	async function fetchUserInfo(accessToken: string) {
		try {
			// Use the new getUserInfo function from our lib
			const userData = await getUserInfo(accessToken);
			if (userData) {
				authData.userEmail = userData.email;
			} else {
				authData.userEmail = null;
			}
		} catch (error) {
			console.error('Error fetching user info:', error);
			authData.userEmail = null;
		}
	}
	
	async function disconnectGoogle() {
		try {
			// First revoke the token at Google using our API
			const accessToken = localStorage.getItem('google_access_token');
			if (accessToken) {
				await revokeToken(accessToken);
			}
			
			// Remove tokens from local storage
			localStorage.removeItem('google_access_token');
			localStorage.removeItem('google_refresh_token');
			
			// Update auth state
			authData.isConnected = false;
			authData.token = null;
			authData.userEmail = null;
			
			// Clear any selected sheets data
			sheetsData.availableSheets = [];
			sheetsData.selectedSheet = null;
			sheetsData.sheetData = [];
		} catch (error) {
			console.error('Error disconnecting from Google:', error);
			authData.error = 'Failed to disconnect from Google';
		}
	}

	// Step navigation
	function nextStep() {
		if (validateCurrentStep()) {
			currentStep = Math.min(currentStep + 1, totalSteps - 1);
			if (currentStep === 2) {
				loadRecentSheets();
			}
		}
	}

	function prevStep() {
		currentStep = Math.max(currentStep - 1, 0);
	}

	function validateCurrentStep(): boolean {
		errors = {};
		
		if (currentStep === 0) {
			if (!authData.isConnected) {
				errors.auth = 'Please connect your Google account to continue';
				return false;
			}
		} else if (currentStep === 1) {
			if (!eventData.name.trim()) {
				errors.name = 'Event name is required';
			}
			if (!eventData.date) {
				errors.date = 'Event date is required';
			}
		} else if (currentStep === 2) {
			if (!sheetsData.selectedSheet) {
				errors.sheet = 'Please select a Google Sheet';
			}
			
			if (sheetsData.selectedSheet) {
				// Validate column mappings
				const { name, surname, email, confirmation } = sheetsData.columnMapping;
				const missingColumns = [];
				
				if (!name) missingColumns.push('Name');
				if (!surname) missingColumns.push('Surname');
				if (!email) missingColumns.push('Email');
				if (!confirmation) missingColumns.push('Confirmation');
				
				if (missingColumns.length > 0) {
					errors.sheetData = `Please map the following columns: ${missingColumns.join(', ')}`;
				}
			}
		} else if (currentStep === 3) {
			if (!emailData.subject.trim()) {
				errors.subject = 'Email subject is required';
			}
			if (!emailData.body.trim()) {
				errors.body = 'Email body is required';
			}
		}

		return Object.keys(errors).length === 0;
	}

	// Google Sheets functions
	async function loadRecentSheets() {
		sheetsData.loading = true;
		// Always expand the sheet list when loading new sheets
		sheetsData.expandedSheetList = true;
		
		try {
			// Use the new unified API endpoint
			const response = await fetch('/private/api/google/sheets/recent', {
				method: 'GET',
				headers: {
					'Authorization': `Bearer ${localStorage.getItem('google_refresh_token')}`
				}
			});
			
			if (response.ok) {
				sheetsData.availableSheets = await response.json();
			}
		} catch (error) {
			console.error('Error loading sheets:', error);
			errors.sheets = 'Failed to load Google Sheets';
		} finally {
			sheetsData.loading = false;
		}
	}

	async function selectSheet(sheet: GoogleSheet) {
		const sameSheet = sheetsData.selectedSheet?.id === sheet.id;
		
		sheetsData.selectedSheet = sheet;
		sheetsData.loading = true;
		
		// Collapse sheet list when selecting a new sheet
		if (!sameSheet) {
			sheetsData.expandedSheetList = false;
		}
		
		try {
			// Use the new unified API endpoint
			const response = await fetch(`/private/api/google/sheets/${sheet.id}/data`, {
				method: 'GET',
				headers: {
					'Authorization': `Bearer ${localStorage.getItem('google_refresh_token')}`
				}
			});
			
			if (response.ok) {
				const data = await response.json();
				sheetsData.sheetData = data.values || [];
			}
		} catch (error) {
			console.error('Error loading sheet data:', error);
			errors.sheetData = 'Failed to load sheet data';
		} finally {
			sheetsData.loading = false;
		}
	}
	
	// Toggle the sheet list expansion
	function toggleSheetList() {
		sheetsData.expandedSheetList = !sheetsData.expandedSheetList;
	}

	// Final submission
	async function createEvent() {
		if (!validateCurrentStep()) return;

		loading = true;
		try {
			const { error } = await data.supabase.rpc('create_event', {
				p_name: eventData.name,
				p_date: eventData.date,
				p_email_subject: emailData.subject,
				p_email_body: emailData.body,
				p_sheet_id: sheetsData.selectedSheet?.id,
				p_name_column: sheetsData.columnMapping.name,
				p_surname_column: sheetsData.columnMapping.surname,
				p_email_column: sheetsData.columnMapping.email,
				p_confirmation_column: sheetsData.columnMapping.confirmation
			});

			if (error) throw error;

			// Redirect to events list or show success message
			goto('/private/events');
		} catch (error) {
			console.error('Error creating event:', error);
			errors.submit = 'Failed to create event. Please try again.';
		} finally {
			loading = false;
		}
	}

	// Computed values
	let canProceed = $derived(() => {
		if (currentStep === 0) return authData.isConnected;
		if (currentStep === 1) return eventData.name && eventData.date;
		if (currentStep === 2) {
			const { name, surname, email, confirmation } = sheetsData.columnMapping;
			return sheetsData.selectedSheet && name && surname && email && confirmation;
		}
		if (currentStep === 3) return emailData.subject && emailData.body;
		return false;
	});
</script>

<div class="max-w-4xl mx-auto p-6">
	<!-- Header -->
	<StepNavigator {currentStep} {totalSteps} />

	<!-- Step Content -->
	<div class="rounded-lg border border-gray-300 bg-white p-6 mb-4">
		{#if currentStep === 0}
			<GoogleAuthStep 
				bind:errors
				onSuccess={(token) => {
					authData.error = null;
					authData.token = token;
					authData.isConnected = true;
					setTimeout(checkGoogleAuth, 100);
				}}
				onError={(error) => {
					authData.error = error;
					authData.isConnected = false;
				}}
			/>
		{:else if currentStep === 1}
			<EventDetailsStep bind:eventData bind:errors />
		{:else if currentStep === 2}
			<GoogleSheetsStep bind:sheetsData bind:errors {loadRecentSheets} {selectSheet} {toggleSheetList} />
		{:else if currentStep === 3}
			<EmailSettingsStep bind:emailData bind:errors />
		{/if}

		{#if errors.submit}
			<div class="mt-4 p-3 bg-red-50 border border-red-200 rounded">
				<p class="text-sm text-red-600">{errors.submit}</p>
			</div>
		{/if}
	</div>

	<!-- Navigation -->
	<StepNavigation 
		{currentStep} 
		{totalSteps} 
		{canProceed} 
		{loading} 
		{prevStep} 
		{nextStep} 
		{createEvent} 
	/>
</div>
