<script lang="ts">
	import { onMount } from 'svelte';
	import { PUBLIC_API_URL } from '$env/static/public';

	const API_BASE = (PUBLIC_API_URL || 'http://localhost:8000') + '/api/v1';

	// State
	let loading = false;
	let error = '';
	let metadata: any = null;
	let data: any[] = [];
	let statistics: any = null;

	// Filters
	let selectedYear = 2007;
	let selectedContinent = '';
	let selectedMetric: 'lifeExp' | 'pop' | 'gdpPercap' = 'gdpPercap';
	let topN = 15;

	// Animation state
	let isPlaying = false;
	let animationInterval: any = null;
	let years: number[] = [];

	// Tabs
	let activeTab: 'scatter' | 'barrace' | 'trends' = 'scatter';

	// Chart containers
	let scatterContainer: HTMLDivElement;
	let barRaceContainer: HTMLDivElement;
	let trendsContainer: HTMLDivElement;

	// Plotly reference
	let Plotly: any;

	onMount(async () => {
		// Load Plotly dynamically
		const script = document.createElement('script');
		script.src = 'https://cdn.plot.ly/plotly-2.27.0.min.js';
		script.onload = () => {
			Plotly = (window as any).Plotly;
			loadData();
		};
		document.head.appendChild(script);
	});

	async function loadData() {
		loading = true;
		error = '';
		try {
			// Load metadata
			const metaRes = await fetch(`${API_BASE}/eda/metadata`);
			metadata = await metaRes.json();
			years = metadata.years;

			// Load initial data
			await updateCharts();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to load data';
		} finally {
			loading = false;
		}
	}

	async function updateCharts() {
		if (!Plotly) return;

		try {
			// Fetch filtered data
			const params = new URLSearchParams();
			if (selectedYear) params.append('year', selectedYear.toString());
			if (selectedContinent) params.append('continent', selectedContinent);

			const dataRes = await fetch(`${API_BASE}/eda/data?${params}`);
			const result = await dataRes.json();
			data = result.data;

			// Fetch statistics
			const statsRes = await fetch(
				`${API_BASE}/eda/statistics?column=${selectedMetric}&group_by=continent&year=${selectedYear}`
			);
			statistics = await statsRes.json();

			// Update active chart
			if (activeTab === 'scatter') renderScatterPlot();
			else if (activeTab === 'barrace') renderBarRace();
			else if (activeTab === 'trends') renderTrends();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to update charts';
		}
	}

	function renderScatterPlot() {
		if (!scatterContainer || !Plotly || data.length === 0) return;

		const continents = [...new Set(data.map((d) => d.continent))];
		// Plotly Express default color sequence
		const colors: Record<string, string> = {
			Africa: '#636EFA',
			Americas: '#EF553B',
			Asia: '#00CC96',
			Europe: '#AB63FA',
			Oceania: '#FFA15A'
		};

		// Calculate max population for scaling (like Plotly Express does)
		const maxPop = Math.max(...data.map((d) => d.pop));
		const sizeMax = 60; // Match original Streamlit app size_max=60

		const traces = continents.map((continent) => {
			const filtered = data.filter((d) => d.continent === continent);
			return {
				x: filtered.map((d) => d.gdpPercap),
				y: filtered.map((d) => d.lifeExp),
				mode: 'markers',
				name: continent,
				text: filtered.map((d) => `${d.country}<br>Pop: ${(d.pop / 1e6).toFixed(1)}M`),
				marker: {
					// Plotly Express uses sqrt scaling with sizeref
					size: filtered.map((d) => d.pop),
					sizemode: 'area',
					sizeref: (2 * maxPop) / (sizeMax * sizeMax),
					sizemin: 4,
					color: colors[continent],
					opacity: 0.7,
					line: { width: 1, color: 'white' }
				},
				hovertemplate:
					'<b>%{text}</b><br>GDP: $%{x:,.0f}<br>Life Exp: %{y:.1f} years<extra></extra>'
			};
		});

		const layout = {
			title: `GDP per Capita vs Life Expectancy (${selectedYear})`,
			xaxis: {
				title: 'GDP per Capita (log scale)',
				type: 'log',
				range: [2.5, 5.2]
			},
			yaxis: {
				title: 'Life Expectancy (years)',
				range: [20, 90]
			},
			showlegend: true,
			legend: { x: 0.02, y: 0.98 },
			hovermode: 'closest',
			paper_bgcolor: 'rgba(0,0,0,0)',
			plot_bgcolor: 'rgba(0,0,0,0)',
			font: { family: 'Inter, system-ui, sans-serif' }
		};

		Plotly.newPlot(scatterContainer, traces, layout, { responsive: true });
	}

	async function renderBarRace() {
		if (!barRaceContainer || !Plotly) return;

		try {
			const res = await fetch(
				`${API_BASE}/eda/ranking?year=${selectedYear}&metric=${selectedMetric}&top_n=${topN}`
			);
			const result = await res.json();

			const colors: Record<string, string> = {
				Africa: '#636EFA',
				Americas: '#EF553B',
				Asia: '#00CC96',
				Europe: '#AB63FA',
				Oceania: '#FFA15A'
			};

			const metricLabels: Record<string, string> = {
				gdpPercap: 'GDP per Capita ($)',
				lifeExp: 'Life Expectancy (years)',
				pop: 'Population'
			};

			const sortedData = result.data.sort(
				(a: any, b: any) => a[selectedMetric] - b[selectedMetric]
			);

			const trace = {
				type: 'bar',
				x: sortedData.map((d: any) => d[selectedMetric]),
				y: sortedData.map((d: any) => d.country),
				orientation: 'h',
				marker: {
					color: sortedData.map((d: any) => colors[d.continent])
				},
				text: sortedData.map((d: any) =>
					selectedMetric === 'pop'
						? `${(d[selectedMetric] / 1e6).toFixed(1)}M`
						: selectedMetric === 'gdpPercap'
							? `$${d[selectedMetric].toFixed(0)}`
							: d[selectedMetric].toFixed(1)
				),
				textposition: 'outside',
				hovertemplate: '<b>%{y}</b><br>%{x:,.0f}<extra></extra>'
			};

			const layout = {
				title: `Top ${topN} Countries by ${metricLabels[selectedMetric]} (${selectedYear})`,
				xaxis: { title: metricLabels[selectedMetric] },
				yaxis: { automargin: true },
				paper_bgcolor: 'rgba(0,0,0,0)',
				plot_bgcolor: 'rgba(0,0,0,0)',
				font: { family: 'Inter, system-ui, sans-serif' },
				margin: { l: 150 }
			};

			Plotly.newPlot(barRaceContainer, [trace], layout, { responsive: true });
		} catch (e) {
			console.error('Bar race error:', e);
		}
	}

	async function renderTrends() {
		if (!trendsContainer || !Plotly) return;

		try {
			// Get top 10 countries by latest value
			const res = await fetch(
				`${API_BASE}/eda/timeseries?metric=${selectedMetric}&top_n=10${selectedContinent ? `&continent=${selectedContinent}` : ''}`
			);
			const result = await res.json();

			const countries = [...new Set(result.data.map((d: any) => d.country))];

			const traces = countries.map((country) => {
				const countryData = result.data
					.filter((d: any) => d.country === country)
					.sort((a: any, b: any) => a.year - b.year);
				return {
					x: countryData.map((d: any) => d.year),
					y: countryData.map((d: any) => d[selectedMetric]),
					mode: 'lines+markers',
					name: country,
					hovertemplate: `<b>${country}</b><br>Year: %{x}<br>Value: %{y:,.0f}<extra></extra>`
				};
			});

			const metricLabels: Record<string, string> = {
				gdpPercap: 'GDP per Capita ($)',
				lifeExp: 'Life Expectancy (years)',
				pop: 'Population'
			};

			const layout = {
				title: `${metricLabels[selectedMetric]} Over Time (Top 10)`,
				xaxis: { title: 'Year', dtick: 5 },
				yaxis: { title: metricLabels[selectedMetric] },
				showlegend: true,
				legend: { x: 1.02, y: 1 },
				paper_bgcolor: 'rgba(0,0,0,0)',
				plot_bgcolor: 'rgba(0,0,0,0)',
				font: { family: 'Inter, system-ui, sans-serif' }
			};

			Plotly.newPlot(trendsContainer, traces, layout, { responsive: true });
		} catch (e) {
			console.error('Trends error:', e);
		}
	}

	// Animation controls
	function playAnimation() {
		if (isPlaying) {
			stopAnimation();
			return;
		}

		isPlaying = true;
		let yearIndex = years.indexOf(selectedYear);

		animationInterval = setInterval(() => {
			yearIndex = (yearIndex + 1) % years.length;
			selectedYear = years[yearIndex];
			updateCharts();
		}, 1000);
	}

	function stopAnimation() {
		isPlaying = false;
		if (animationInterval) {
			clearInterval(animationInterval);
			animationInterval = null;
		}
	}

	// Reactive updates
	$: if (Plotly && (selectedYear || selectedContinent || selectedMetric)) {
		updateCharts();
	}

	$: if (Plotly && activeTab) {
		// Stop animation when switching to trends tab
		if (activeTab === 'trends' && isPlaying) {
			stopAnimation();
		}
		setTimeout(() => {
			if (activeTab === 'scatter') renderScatterPlot();
			else if (activeTab === 'barrace') renderBarRace();
			else if (activeTab === 'trends') renderTrends();
		}, 100);
	}
</script>

<div class="max-w-7xl mx-auto animate-fade-in">
	<!-- Header -->
	<div class="mb-6">
		<h1 class="text-2xl font-bold text-surface-800">EDA Gapminder</h1>
		<p class="text-surface-600 mt-1">
			Explore global development data: GDP, life expectancy, and population trends (1952-2007)
		</p>
	</div>

	{#if error}
		<div class="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg mb-4">
			{error}
		</div>
	{/if}

	<div class="grid grid-cols-1 lg:grid-cols-4 gap-4">
		<!-- Filters Panel -->
		<div class="card p-4">
			<h3 class="text-sm font-semibold text-surface-700 mb-4">Filters</h3>

			<!-- Year Slider (disabled on Line Trends) -->
			<div class="mb-4 {activeTab === 'trends' ? 'opacity-50' : ''}">
				<label class="block text-xs font-medium text-surface-600 mb-2">
					Year: <span class="text-primary-600 font-bold">{selectedYear}</span>
					{#if activeTab === 'trends'}
						<span class="text-surface-400">(N/A for trends)</span>
					{/if}
				</label>
				<input
					type="range"
					min="1952"
					max="2007"
					step="5"
					bind:value={selectedYear}
					disabled={activeTab === 'trends'}
					class="w-full h-2 bg-surface-200 rounded-lg appearance-none cursor-pointer disabled:cursor-not-allowed"
				/>
				<div class="flex justify-between text-xs text-surface-500 mt-1">
					<span>1952</span>
					<span>2007</span>
				</div>
			</div>

			<!-- Play/Pause Animation (only for Scatter/Bar Race) -->
			{#if activeTab !== 'trends'}
				<button
					on:click={playAnimation}
					class="w-full mb-4 px-4 py-2 rounded-lg text-sm font-medium transition-colors
						{isPlaying
						? 'bg-red-100 text-red-700 hover:bg-red-200'
						: 'bg-primary-100 text-primary-700 hover:bg-primary-200'}"
				>
					{isPlaying ? 'Stop Animation' : 'Play Timeline'}
				</button>
			{:else}
				<div class="mb-4 px-4 py-2 rounded-lg text-sm text-surface-500 bg-surface-100 text-center">
					Line Trends shows all years
				</div>
			{/if}

			<!-- Continent Filter -->
			<div class="mb-4">
				<label class="block text-xs font-medium text-surface-600 mb-2">Continent</label>
				<select bind:value={selectedContinent} class="input w-full">
					<option value="">All Continents</option>
					{#if metadata}
						{#each metadata.continents as continent}
							<option value={continent}>{continent}</option>
						{/each}
					{/if}
				</select>
			</div>

			<!-- Metric Selector -->
			<div class="mb-4">
				<label class="block text-xs font-medium text-surface-600 mb-2">Metric</label>
				<select bind:value={selectedMetric} class="input w-full">
					<option value="gdpPercap">GDP per Capita</option>
					<option value="lifeExp">Life Expectancy</option>
					<option value="pop">Population</option>
				</select>
			</div>

			<!-- Top N / Countries display -->
			<div class="mb-4">
				{#if activeTab === 'barrace'}
					<label for="topn-slider" class="block text-xs font-medium text-surface-600 mb-2">
						Top N Countries: <span class="text-primary-600 font-bold">{topN}</span>
					</label>
					<input
						id="topn-slider"
						type="range"
						min="5"
						max="25"
						step="5"
						bind:value={topN}
						class="w-full h-2 bg-surface-200 rounded-lg appearance-none cursor-pointer"
					/>
				{:else}
					<label class="block text-xs font-medium text-surface-600 mb-2">
						Countries: <span class="text-primary-600 font-bold">{data.length || 142}</span>
					</label>
					<div class="text-xs text-surface-400">All countries displayed</div>
				{/if}
			</div>

			<!-- Statistics Panel -->
			{#if statistics}
				<div class="border-t border-surface-200 pt-4 mt-4">
					<h4 class="text-xs font-semibold text-surface-700 mb-3">
						Statistics ({selectedYear})
					</h4>
					<div class="space-y-2 text-xs">
						<div class="flex justify-between">
							<span class="text-surface-500">Mean:</span>
							<span class="font-medium">{statistics.mean.toFixed(2)}</span>
						</div>
						<div class="flex justify-between">
							<span class="text-surface-500">Median:</span>
							<span class="font-medium">{statistics.median.toFixed(2)}</span>
						</div>
						<div class="flex justify-between">
							<span class="text-surface-500">Std Dev:</span>
							<span class="font-medium">{statistics.std.toFixed(2)}</span>
						</div>
						<div class="flex justify-between">
							<span class="text-surface-500">Min:</span>
							<span class="font-medium">{statistics.min.toFixed(2)}</span>
						</div>
						<div class="flex justify-between">
							<span class="text-surface-500">Max:</span>
							<span class="font-medium">{statistics.max.toFixed(2)}</span>
						</div>
					</div>
				</div>
			{/if}
		</div>

		<!-- Main Visualization Area -->
		<div class="lg:col-span-3 card p-4">
			<!-- Tabs -->
			<div class="flex border-b border-surface-200 mb-4">
				<button
					class="px-4 py-2 text-sm font-medium transition-colors
						{activeTab === 'scatter'
						? 'text-primary-600 border-b-2 border-primary-600'
						: 'text-surface-500 hover:text-surface-700'}"
					on:click={() => (activeTab = 'scatter')}
				>
					Scatter Plot
				</button>
				<button
					class="px-4 py-2 text-sm font-medium transition-colors
						{activeTab === 'barrace'
						? 'text-primary-600 border-b-2 border-primary-600'
						: 'text-surface-500 hover:text-surface-700'}"
					on:click={() => (activeTab = 'barrace')}
				>
					Bar Chart Race
				</button>
				<button
					class="px-4 py-2 text-sm font-medium transition-colors
						{activeTab === 'trends'
						? 'text-primary-600 border-b-2 border-primary-600'
						: 'text-surface-500 hover:text-surface-700'}"
					on:click={() => (activeTab = 'trends')}
				>
					Line Trends
				</button>
			</div>

			<!-- Chart Container -->
			{#if loading}
				<div class="flex items-center justify-center h-96">
					<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600"></div>
				</div>
			{:else}
				<div class="h-[500px]">
					{#if activeTab === 'scatter'}
						<div bind:this={scatterContainer} class="w-full h-full"></div>
					{:else if activeTab === 'barrace'}
						<div bind:this={barRaceContainer} class="w-full h-full"></div>
					{:else if activeTab === 'trends'}
						<div bind:this={trendsContainer} class="w-full h-full"></div>
					{/if}
				</div>
			{/if}

			<!-- Data Summary -->
			{#if data.length > 0}
				<div class="mt-4 pt-4 border-t border-surface-200">
					<p class="text-xs text-surface-500">
						Showing {data.length} records for {selectedYear}
						{selectedContinent ? ` in ${selectedContinent}` : ''}
					</p>
				</div>
			{/if}
		</div>
	</div>
</div>

<style>
	.card {
		background: linear-gradient(135deg, #fdf8f3 0%, #faf5ee 100%);
		border-radius: 12px;
		box-shadow:
			0 1px 3px rgba(0, 0, 0, 0.05),
			0 1px 2px rgba(0, 0, 0, 0.03);
	}

	.input {
		padding: 0.5rem 0.75rem;
		border: 1px solid #e5e7eb;
		border-radius: 8px;
		font-size: 0.875rem;
		background: white;
	}

	.input:focus {
		outline: none;
		border-color: #8b5cf6;
		box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
	}

	input[type='range'] {
		-webkit-appearance: none;
		appearance: none;
	}

	input[type='range']::-webkit-slider-thumb {
		-webkit-appearance: none;
		appearance: none;
		width: 16px;
		height: 16px;
		border-radius: 50%;
		background: #8b5cf6;
		cursor: pointer;
	}

	.animate-fade-in {
		animation: fadeIn 0.3s ease-out;
	}

	@keyframes fadeIn {
		from {
			opacity: 0;
			transform: translateY(10px);
		}
		to {
			opacity: 1;
			transform: translateY(0);
		}
	}
</style>
