<script lang="ts">
	import Navbar from '$lib/components/Navbar.svelte';
	import Footer from '$lib/components/Footer.svelte';

	// API Base - uses env var for local dev, defaults to cockpit for production
	const API_BASE = (import.meta.env.VITE_API_URL || 'https://cockpit.valuecurve.co') + '/api/v1';

	// State
	let loading = $state(false);
	let error = $state('');
	let metadata: any = $state(null);
	let houseData: any[] = $state([]);
	let statistics: any = $state(null);
	let prediction: any = $state(null);

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

	// Prediction inputs
	let predBedrooms = $state(3);
	let predBathrooms = $state(2);
	let predSqft = $state(2000);
	let predAge = $state(10);

	// Tabs
	let activeTab: 'map' | 'distribution' | 'correlation' = $state('map');

	// Chart containers
	let mapContainer: HTMLDivElement;
	let distContainer: HTMLDivElement;
	let corrContainer: HTMLDivElement;

	// Plotly reference
	let Plotly: any = $state(null);
	let plotlyLoaded = $state(false);

	// Load Plotly on mount
	$effect(() => {
		if (typeof window !== 'undefined' && !plotlyLoaded) {
			const script = document.createElement('script');
			script.src = 'https://cdn.plot.ly/plotly-2.27.0.min.js';
			script.onload = () => {
				Plotly = (window as any).Plotly;
				plotlyLoaded = true;
				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 | Build with AI</title>
	<meta name="description" content="Seattle/King County house price prediction and visualization tool with ML-powered estimates." />
</svelte:head>

<div class="min-h-screen bg-gradient-to-b from-slate-50 to-white">
	<Navbar />

	<main class="pt-24 pb-16 px-6">
		<div class="max-w-7xl mx-auto">
			<!-- Header -->
			<div class="mb-6">
				<a href="/tools" class="text-primary-600 hover:text-primary-700 text-sm mb-2 inline-block">&larr; Back to Tools</a>
				<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 & Selection -->
					<div class="lg:col-span-1 space-y-4">
						<!-- Filters Card -->
						<div class="bg-white rounded-xl shadow-sm p-3 border border-gray-100">
							<h2 class="text-sm font-semibold mb-3 flex items-center gap-1">
								<span>Filters</span>
							</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
									onclick={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-sm p-3 border border-gray-100">
							<h2 class="text-sm font-semibold mb-3 flex items-center gap-1">
								<span>Selection</span>
							</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-sm border border-gray-100 overflow-hidden">
							<!-- Tabs -->
							<div class="flex border-b border-gray-200">
								<button
									onclick={() => 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
									onclick={() => 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
									onclick={() => 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
										onclick={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-sm p-3 border border-gray-100">
							<h2 class="text-sm font-semibold mb-3 flex items-center gap-1">
								<span>Stats</span>
							</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>
	</main>

	<Footer />
</div>
