<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 houseData: any[] = [];
	let statistics: any = null;
	let prediction: any = null;

	// Filters
	let minPrice = 0;
	let maxPrice = 8000000;
	let minBedrooms = 0;
	let maxBedrooms = 10;
	let waterfrontOnly = false;
	let selectedZipcode = '';

	// Prediction inputs
	let predBedrooms = 3;
	let predBathrooms = 2;
	let predSqft = 2000;
	let predAge = 10;

	// Tabs
	let activeTab: 'map' | 'distribution' | 'correlation' = 'map';

	// Chart containers
	let mapContainer: HTMLDivElement;
	let distContainer: HTMLDivElement;
	let corrContainer: 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}/house/metadata`);
			metadata = await metaRes.json();

			// Load initial data and charts
			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 house data
			const params = new URLSearchParams();
			if (minPrice > 0) params.append('min_price', minPrice.toString());
			if (maxPrice < 8000000) params.append('max_price', maxPrice.toString());
			if (minBedrooms > 0) params.append('min_bedrooms', minBedrooms.toString());
			if (maxBedrooms < 10) params.append('max_bedrooms', maxBedrooms.toString());
			if (waterfrontOnly) params.append('waterfront', 'true');
			if (selectedZipcode) params.append('zipcode', selectedZipcode);
			params.append('sample_size', '2000');

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

			// Fetch statistics
			const statsRes = await fetch(`${API_BASE}/house/statistics`);
			statistics = await statsRes.json();

			// Update active chart (small delay to ensure DOM is ready)
			setTimeout(() => {
				if (activeTab === 'map') renderMap();
				else if (activeTab === 'distribution') renderDistribution();
				else if (activeTab === 'correlation') renderCorrelation();
			}, 50);
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to update charts';
		}
	}

	function renderMap() {
		if (!mapContainer || !Plotly || houseData.length === 0) return;

		// Color scale based on price
		const prices = houseData.map((d) => d.price);
		const minP = Math.min(...prices);
		const maxP = Math.max(...prices);

		const trace = {
			type: 'scattermapbox',
			lat: houseData.map((d) => d.lat),
			lon: houseData.map((d) => d.long),
			mode: 'markers',
			marker: {
				size: houseData.map((d) => Math.max(5, Math.sqrt(d.sqft_living / 100))),
				color: houseData.map((d) => d.price),
				colorscale: 'Viridis',
				cmin: minP,
				cmax: maxP,
				colorbar: {
					title: 'Price ($)',
					tickformat: ',.0f'
				},
				opacity: 0.7
			},
			text: houseData.map(
				(d) =>
					`Price: $${d.price.toLocaleString()}<br>` +
					`Beds: ${d.bedrooms} | Baths: ${d.bathrooms}<br>` +
					`Sqft: ${d.sqft_living.toLocaleString()}<br>` +
					`Year Built: ${d.yr_built}<br>` +
					`Grade: ${d.grade}`
			),
			hoverinfo: 'text'
		};

		const layout = {
			mapbox: {
				style: 'open-street-map',
				center: {
					lat: metadata?.location?.center?.[0] || 47.5,
					lon: metadata?.location?.center?.[1] || -122.2
				},
				zoom: 9
			},
			margin: { l: 0, r: 0, t: 30, b: 0 },
			title: {
				text: `King County House Prices (${houseData.length} houses shown)`,
				font: { size: 16 }
			},
			height: 500
		};

		Plotly.newPlot(mapContainer, [trace], layout, { responsive: true });
	}

	async function renderDistribution() {
		if (!distContainer || !Plotly) return;

		try {
			const res = await fetch(`${API_BASE}/house/price-distribution?bins=30`);
			const dist = await res.json();

			const trace = {
				x: dist.bin_centers,
				y: dist.counts,
				type: 'bar',
				marker: {
					color: dist.bin_centers,
					colorscale: 'Viridis'
				}
			};

			const layout = {
				title: 'Price Distribution',
				xaxis: {
					title: 'Price ($)',
					tickformat: ',.0f'
				},
				yaxis: { title: 'Count' },
				margin: { l: 60, r: 30, t: 50, b: 60 },
				height: 400
			};

			Plotly.newPlot(distContainer, [trace], layout, { responsive: true });
		} catch (e) {
			console.error('Failed to render distribution:', e);
		}
	}

	async function renderCorrelation() {
		if (!corrContainer || !Plotly) return;

		try {
			const res = await fetch(`${API_BASE}/house/correlation`);
			const corr = await res.json();

			const trace = {
				z: corr.correlation,
				x: corr.columns,
				y: corr.columns,
				type: 'heatmap',
				colorscale: 'RdBu',
				zmin: -1,
				zmax: 1,
				colorbar: { title: 'Correlation' }
			};

			const layout = {
				title: 'Feature Correlation Matrix',
				margin: { l: 100, r: 30, t: 50, b: 100 },
				height: 500,
				xaxis: { tickangle: 45 },
				yaxis: { autorange: 'reversed' }
			};

			Plotly.newPlot(corrContainer, [trace], layout, { responsive: true });
		} catch (e) {
			console.error('Failed to render correlation:', e);
		}
	}

	async function predictPrice() {
		try {
			const res = await fetch(`${API_BASE}/house/predict`, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({
					bedrooms: predBedrooms,
					bathrooms: predBathrooms,
					sqft: predSqft,
					age: predAge
				})
			});
			prediction = await res.json();
		} catch (e) {
			error = 'Prediction failed';
		}
	}

	function handleTabChange(tab: 'map' | 'distribution' | 'correlation') {
		activeTab = tab;
		setTimeout(() => {
			if (tab === 'map') renderMap();
			else if (tab === 'distribution') renderDistribution();
			else if (tab === 'correlation') renderCorrelation();
		}, 100);
	}

	function formatCurrency(value: number): string {
		return new Intl.NumberFormat('en-US', {
			style: 'currency',
			currency: 'USD',
			minimumFractionDigits: 0,
			maximumFractionDigits: 0
		}).format(value);
	}
</script>

<svelte:head>
	<title>House Price Predictor | AI Tools Suite</title>
</svelte:head>

<div class="p-6 max-w-7xl mx-auto">
	<!-- Header -->
	<div class="mb-6">
		<h1 class="text-2xl font-bold text-gray-900">🏠 House Price Predictor</h1>
		<p class="text-gray-600 mt-1">
			Seattle/King County house price prediction and visualization (21,613 houses, 2014-2015)
		</p>
	</div>

	{#if loading}
		<div class="flex items-center justify-center h-64">
			<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600"></div>
		</div>
	{:else if error}
		<div class="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg mb-4">
			{error}
		</div>
	{:else}
		<div class="grid grid-cols-1 lg:grid-cols-6 gap-4">
			<!-- Left Panel: Filters & Prediction -->
			<div class="lg:col-span-1 space-y-4">
				<!-- Filters Card -->
				<div class="bg-white rounded-xl shadow-soft p-3 border border-gray-100">
					<h2 class="text-sm font-semibold mb-3 flex items-center gap-1">
						<span>🔍</span> Filters
					</h2>

					<div class="space-y-3">
						<div>
							<span class="block text-xs font-medium text-gray-700 mb-1">Price Range</span>
							<div class="flex gap-2">
								<input
									type="number"
									bind:value={minPrice}
									class="w-1/2 px-2 py-1 text-sm border rounded"
									placeholder="Min"
								/>
								<input
									type="number"
									bind:value={maxPrice}
									class="w-1/2 px-2 py-1 text-sm border rounded"
									placeholder="Max"
								/>
							</div>
						</div>

						<div>
							<span class="block text-xs font-medium text-gray-700 mb-1">Bedrooms</span>
							<div class="flex gap-2">
								<input
									type="number"
									bind:value={minBedrooms}
									min="0"
									max="10"
									class="w-1/2 px-2 py-1 text-sm border rounded"
								/>
								<input
									type="number"
									bind:value={maxBedrooms}
									min="0"
									max="10"
									class="w-1/2 px-2 py-1 text-sm border rounded"
								/>
							</div>
						</div>

						<div>
							<span class="block text-xs font-medium text-gray-700 mb-1">Zipcode</span>
							<select bind:value={selectedZipcode} class="w-full px-2 py-1 text-sm border rounded">
								<option value="">All Zipcodes</option>
								{#if metadata?.zipcodes}
									{#each metadata.zipcodes as zip}
										<option value={zip}>{zip}</option>
									{/each}
								{/if}
							</select>
						</div>

						<label class="flex items-center gap-2">
							<input type="checkbox" bind:checked={waterfrontOnly} class="rounded" />
							<span class="text-sm text-gray-700">Waterfront only</span>
						</label>

						<button
							on:click={updateCharts}
							class="w-full bg-primary-600 text-white py-2 rounded-lg hover:bg-primary-700 transition-colors"
						>
							Apply Filters
						</button>
					</div>
				</div>

				<!-- Selection Card -->
				<div class="bg-white rounded-xl shadow-soft p-3 border border-gray-100">
					<h2 class="text-sm font-semibold mb-3 flex items-center gap-1">
						<span>🏠</span> Selection
					</h2>

					<div class="space-y-3">
						<div>
							<span class="block text-xs font-medium text-gray-700 mb-1">
								Beds: {predBedrooms}
							</span>
							<input
								type="range"
								bind:value={predBedrooms}
								min="1"
								max="10"
								class="w-full"
							/>
						</div>

						<div>
							<span class="block text-xs font-medium text-gray-700 mb-1">
								Baths: {predBathrooms}
							</span>
							<input
								type="range"
								bind:value={predBathrooms}
								min="1"
								max="6"
								step="0.5"
								class="w-full"
							/>
						</div>

						<div>
							<span class="block text-xs font-medium text-gray-700 mb-1">
								Sqft: {predSqft.toLocaleString()}
							</span>
							<input
								type="range"
								bind:value={predSqft}
								min="500"
								max="10000"
								step="100"
								class="w-full"
							/>
						</div>

						<div>
							<span class="block text-xs font-medium text-gray-700 mb-1">
								Age: {predAge}yr
							</span>
							<input
								type="range"
								bind:value={predAge}
								min="0"
								max="120"
								class="w-full"
							/>
						</div>
					</div>
				</div>
			</div>

			<!-- Main Chart Area -->
			<div class="lg:col-span-4">
				<div class="bg-white rounded-xl shadow-soft border border-gray-100 overflow-hidden">
					<!-- Tabs -->
					<div class="flex border-b border-gray-200">
						<button
							on:click={() => handleTabChange('map')}
							class="flex-1 px-4 py-3 text-sm font-medium transition-colors
								{activeTab === 'map'
								? 'bg-primary-50 text-primary-700 border-b-2 border-primary-600'
								: 'text-gray-600 hover:bg-gray-50'}"
						>
							🗺️ Map View
						</button>
						<button
							on:click={() => handleTabChange('distribution')}
							class="flex-1 px-4 py-3 text-sm font-medium transition-colors
								{activeTab === 'distribution'
								? 'bg-primary-50 text-primary-700 border-b-2 border-primary-600'
								: 'text-gray-600 hover:bg-gray-50'}"
						>
							📊 Distribution
						</button>
						<button
							on:click={() => handleTabChange('correlation')}
							class="flex-1 px-4 py-3 text-sm font-medium transition-colors
								{activeTab === 'correlation'
								? 'bg-primary-50 text-primary-700 border-b-2 border-primary-600'
								: 'text-gray-600 hover:bg-gray-50'}"
						>
							🔗 Correlations
						</button>
					</div>

					<!-- Chart Containers -->
					<div class="p-4">
						<div bind:this={mapContainer} class:hidden={activeTab !== 'map'}></div>
						<div bind:this={distContainer} class:hidden={activeTab !== 'distribution'}></div>
						<div bind:this={corrContainer} class:hidden={activeTab !== 'correlation'}></div>
					</div>

					<!-- Predict Price Bar -->
					<div class="px-4 py-3 bg-gray-50 border-t border-gray-200 flex items-center justify-between gap-4">
						<div class="flex items-center gap-4 text-sm text-gray-600">
							<span>🏠 {predBedrooms} bed</span>
							<span>🛁 {predBathrooms} bath</span>
							<span>📐 {predSqft.toLocaleString()} sqft</span>
							<span>📅 {predAge}yr old</span>
						</div>
						<div class="flex items-center gap-3">
							<button
								on:click={predictPrice}
								class="px-6 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors font-medium"
							>
								Predict Price
							</button>
							{#if prediction}
								<div class="px-4 py-2 bg-green-100 rounded-lg border border-green-300">
									<span class="text-xl font-bold text-green-700">{prediction.formatted_price}</span>
								</div>
							{/if}
						</div>
					</div>
				</div>
			</div>

			<!-- Right Panel: Statistics -->
			<div class="lg:col-span-1">
				<div class="bg-white rounded-xl shadow-soft p-3 border border-gray-100">
					<h2 class="text-sm font-semibold mb-3 flex items-center gap-1">
						<span>📈</span> Stats
					</h2>

					{#if statistics}
						<div class="space-y-2">
							<div class="p-2 bg-gray-50 rounded-lg">
								<p class="text-xs text-gray-500">Total</p>
								<p class="text-base font-bold text-gray-900">
									{statistics.count?.toLocaleString()}
								</p>
							</div>

							<div class="p-2 bg-blue-50 rounded-lg">
								<p class="text-xs text-blue-600">Avg</p>
								<p class="text-base font-bold text-blue-700">
									{formatCurrency(statistics.mean)}
								</p>
							</div>

							<div class="p-2 bg-green-50 rounded-lg">
								<p class="text-xs text-green-600">Median</p>
								<p class="text-base font-bold text-green-700">
									{formatCurrency(statistics.median)}
								</p>
							</div>

							<div class="grid grid-cols-2 gap-1">
								<div class="p-1 bg-gray-50 rounded text-center">
									<p class="text-xs text-gray-500">Min</p>
									<p class="text-xs font-semibold">{formatCurrency(statistics.min)}</p>
								</div>
								<div class="p-1 bg-gray-50 rounded text-center">
									<p class="text-xs text-gray-500">Max</p>
									<p class="text-xs font-semibold">{formatCurrency(statistics.max)}</p>
								</div>
							</div>

							{#if statistics.percentiles}
								<div class="mt-2 pt-2 border-t border-gray-100">
									<p class="text-xs font-medium text-gray-600 mb-1">Percentiles</p>
									<div class="space-y-0.5 text-xs">
										<div class="flex justify-between">
											<span class="text-gray-500">25th</span>
											<span class="font-medium">{formatCurrency(statistics.percentiles['25'])}</span>
										</div>
										<div class="flex justify-between">
											<span class="text-gray-500">75th</span>
											<span class="font-medium">{formatCurrency(statistics.percentiles['75'])}</span>
										</div>
										<div class="flex justify-between">
											<span class="text-gray-500">90th</span>
											<span class="font-medium">{formatCurrency(statistics.percentiles['90'])}</span>
										</div>
									</div>
								</div>
							{/if}
						</div>
					{/if}

					{#if metadata}
						<div class="mt-3 pt-2 border-t border-gray-100">
							<p class="text-xs text-gray-500">
								{metadata.region}<br/>
								{metadata.data_period}
							</p>
						</div>
					{/if}
				</div>
			</div>
		</div>
	{/if}
</div>
