<script lang="ts">
	import { page } from '$app/stores';
	import { browser } from '$app/environment';
	import { onMount, onDestroy } from 'svelte';
	import type { QueueItem, QueueStatusUpdate } from '$lib/server/queue/types';
	import QueueItemCard from './components/QueueItemCard.svelte';
	import NotificationSettings from './components/NotificationSettings.svelte';
	import { replaceState } from '$app/navigation';

	let items = $state<QueueItem[]>([]);
	let loading = $state(true);
	let error = $state<string | null>(null);
	let filter = $state<string>('all');
	let eventSource = $state<EventSource | null>(null);
	let connectionStatus = $state<'connecting' | 'connected' | 'disconnected'>('disconnected');
	let lastPing = $state<string | null>(null);

	// Get highlighted item ID from URL params (when redirected from Share page)
	let highlightId = $derived($page.url.searchParams.get('highlight'));

	// Available filters - derived to be reactive
	let filters = $derived([
		{ id: 'all', name: 'All Items', count: items.length },
		{ id: 'pending', name: 'Pending', count: items.filter(item => item.status === 'pending').length },
		{ id: 'in_progress', name: 'Processing', count: items.filter(item => item.status === 'in_progress').length },
		{ id: 'success', name: 'Complete', count: items.filter(item => item.status === 'success').length },
		{ id: 'error', name: 'Failed', count: items.filter(item => item.status === 'error' || item.status === 'unhealthy').length }
	]);

	// Filter items based on selected filter
	// Using $derived.by to execute the function and derive the result array
	let filteredItems = $derived.by(() => {
		if (filter === 'all') return items;
		if (filter === 'error') return items.filter(item => item.status === 'error' || item.status === 'unhealthy');
		return items.filter(item => item.status === filter);
	});

	onMount(async () => {
		await loadQueueItems();
		if (browser) {
			startSSEConnection();
		}
	});

	onDestroy(() => {
		if (eventSource) {
			console.log('[SSE] Closing connection on component destroy');
			eventSource.close();
			connectionStatus = 'disconnected';
		}
	});

	async function loadQueueItems() {
		try {
			loading = true;
			error = null;
			
			const response = await fetch('/api/queue');
			if (!response.ok) {
				throw new Error('Failed to load queue items');
			}
			
			const data = await response.json();
			items = data.items || [];
		} catch (e) {
			error = e instanceof Error ? e.message : 'Unknown error';
			console.error('Failed to load queue items:', e);
		} finally {
			loading = false;
		}
	}

	function startSSEConnection() {
		if (!browser) {
			console.error('Cannot start SSE connection on server side');
			return; // Guard: EventSource is browser-only API
		}
		
		connectionStatus = 'connecting';
		console.log('[SSE] Connecting to queue stream...');
		
		try {
			eventSource = new EventSource('/api/queue/stream');
			
			eventSource.addEventListener('open', () => {
				console.log('[SSE] Connection opened');
				connectionStatus = 'connected';
			});
			
			eventSource.addEventListener('connection', (event) => {
				const data = JSON.parse(event.data);
				console.log('[SSE] Connection confirmed:', data.message);
				connectionStatus = 'connected';
			});

			eventSource.addEventListener('queue-update', (event) => {
				const update: QueueStatusUpdate = JSON.parse(event.data);
				updateQueueItem(update);
			});

			eventSource.addEventListener('error', (event) => {
				console.error('[SSE] Connection error:', event);
				connectionStatus = 'disconnected';
				
				// Attempt to reconnect after 5 seconds
				setTimeout(() => {
					// EventSource.CLOSED = 2 (use numeric constant for SSR safety)
					if (eventSource?.readyState === 2) {
						console.log('[SSE] Attempting reconnection...');
						startSSEConnection();
					}
				}, 5000);
			});

			eventSource.addEventListener('ping', (event) => {
				// Keep-alive ping, update last ping timestamp
				const data = JSON.parse(event.data);
				lastPing = data.timestamp;
				console.log('[SSE] Keep-alive ping received at:', data.timestamp);
			});

		} catch (e) {
			console.error('[SSE] Failed to start SSE connection:', e);
			connectionStatus = 'disconnected';
		}
	}

	function updateQueueItem(update: QueueStatusUpdate) {
		// Find and update the item in the list
		const itemIndex = items.findIndex(item => item.id === update.itemId);
		
		if (itemIndex >= 0) {
			// Update existing item
			items[itemIndex] = {
				...items[itemIndex],
				status: update.status,
				phases: update.progress || items[itemIndex].phases,
				results: update.results || items[itemIndex].results,
				error: update.error || items[itemIndex].error,
				updatedAt: update.timestamp
			};
		} else {
			// New item - fetch full details from API
			fetchQueueItem(update.itemId);
		}
		
		// Trigger reactivity
		items = [...items];
	}

	async function fetchQueueItem(id: string) {
		try {
			const response = await fetch(`/api/queue/${id}`);
			if (response.ok) {
				const item = await response.json();
				items = [item, ...items]; // Add to top of list
			}
		} catch (e) {
			console.error('Failed to fetch queue item:', e);
		}
	}

	async function retryItem(id: string) {
		try {
			const response = await fetch(`/api/queue/${id}/retry`, {
				method: 'POST'
			});
			
			if (!response.ok) {
				const errorData = await response.json();
				throw new Error(errorData.message || 'Failed to retry item');
			}
			
			// Item will be updated via SSE
			console.log('Retry initiated for item:', id);
		} catch (e) {
			console.error('Failed to retry item:', e);
			// Could show a toast notification here
		}
	}

	async function removeItem(id: string) {
		try {
			const response = await fetch(`/api/queue/${id}`, {
				method: 'DELETE'
			});

			if (!response.ok) {
				const errorData = await response.json();
				throw new Error(errorData.message || 'Failed to remove item');
			}

			// Item will be removed from local state via SSE update
			// but remove immediately for better UX
			items = items.filter(item => item.id !== id);
			console.log('Item removed successfully:', id);
		} catch (e) {
			console.error('Failed to remove item:', e);
			// Fallback: remove from local state anyway
			items = items.filter(item => item.id !== id);
		}
	}

	function clearHighlight() {
		// Remove highlight parameter from URL without navigation
		const url = new URL(window.location.href);
		url.searchParams.delete('highlight');
		replaceState(url, {});
	}
</script>

<svelte:head>
	<title>InstaRecipe Queue Dashboard</title>
	<meta name="description" content="Monitor your recipe extraction queue in real-time" />
</svelte:head>

<div class="mx-auto p-6 max-w-6xl">
	<!-- Header -->
	<div class="mb-8">
		<h1 class="text-3xl font-bold mb-2">Recipe Queue Dashboard</h1>
		<p class="text-gray-600">Monitor your Instagram recipe extractions in real-time</p>
	</div>

	<!-- Action Bar -->
	<div class="mb-6 flex flex-col sm:flex-row gap-4 justify-between items-start sm:items-center">
		<!-- Filter Tabs -->
		<div class="flex flex-wrap gap-2">
			{#each filters as filterOption}
				<button
					onclick={() => filter = filterOption.id}
					class="px-4 py-2 rounded-lg text-sm font-medium transition-colors {filter === filterOption.id 
						? 'bg-blue-600 text-white' 
						: 'bg-gray-100 text-gray-700 hover:bg-gray-200'}"
				>
					{filterOption.name}
					{#if filterOption.count > 0}
						<span class="ml-1 {filter === filterOption.id ? 'text-blue-100' : 'text-gray-500'}">
							({filterOption.count})
						</span>
					{/if}
				</button>
			{/each}
		</div>

		<!-- Refresh Button -->
		<button
			onclick={loadQueueItems}
			disabled={loading}
			class="flex items-center space-x-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 disabled:opacity-50 transition-colors"
		>
			<svg class="w-4 h-4 {loading ? 'animate-spin' : ''}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
				<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
			</svg>
			<span>Refresh</span>
		</button>
	</div>

	<!-- Loading State -->
	{#if loading}
		<div class="flex justify-center items-center py-12">
			<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
			<span class="ml-3 text-gray-600">Loading queue items...</span>
		</div>
	{/if}

	<!-- Error State -->
	{#if error}
		<div class="bg-red-50 border border-red-200 rounded-lg p-4 mb-6">
			<div class="flex items-center">
				<svg class="w-5 h-5 text-red-400 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
					<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 15.5c-.77.833.192 2.5 1.732 2.5z"></path>
				</svg>
				<span class="text-red-800">Error loading queue: {error}</span>
			</div>
		</div>
	{/if}

	<!-- Queue Items -->
	{#if !loading && filteredItems.length === 0}
		<div class="text-center py-12">
			<div class="text-gray-400 mb-4">
				<svg class="w-16 h-16 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24">
					<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2 2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path>
				</svg>
			</div>
			<h3 class="text-lg font-medium text-gray-900 mb-2">No queue items</h3>
			<p class="text-gray-600 mb-6">
				{#if filter === 'all'}
					Start by sharing an Instagram recipe or adding a URL manually
				{:else}
					No items match the selected filter
				{/if}
			</p>
			<a
				href="/share"
				class="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
			>
				<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
					<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path>
				</svg>
				Add Recipe URL
			</a>
		</div>
	{:else}
		<div class="space-y-4">
			{#each filteredItems as item (item.id)}
				<QueueItemCard 
					{item} 
					highlighted={item.id === highlightId}
					onRetry={() => retryItem(item.id)}
					onRemove={() => removeItem(item.id)}
					onClearHighlight={clearHighlight}
				/>
			{/each}
		</div>
	{/if}

	<!-- Notification Settings - Always visible -->
	<div class="mt-8">
		<NotificationSettings />
	</div>

	<!-- Connection Status -->
	<div class="fixed bottom-4 right-4">
		<div class="flex items-center space-x-2 px-3 py-2 bg-white border rounded-lg shadow-sm text-sm">
			<div class="w-2 h-2 rounded-full {
				connectionStatus === 'connected' ? 'bg-green-400' : 
				connectionStatus === 'connecting' ? 'bg-yellow-400' :
				'bg-red-400'
			}"></div>
			<span class="text-gray-600">
				{connectionStatus === 'connected' ? 'Live updates' : 
				 connectionStatus === 'connecting' ? 'Connecting...' :
				 'Disconnected'}
			</span>
			{#if lastPing}
				<span class="text-xs text-gray-400">
					({new Date(lastPing).toLocaleTimeString()})
				</span>
			{/if}
		</div>
	</div>
</div>
