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

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

	let mode: 'upload-baseline' | 'analyze' | 'compare' = 'upload-baseline';
	let baselineFile: File | null = null;
	let baselineFileName = '';
	let baselineName = '';
	let productionFile: File | null = null;
	let productionFileName = '';
	let compareBaselineFile: File | null = null;
	let compareBaselineFileName = '';
	let compareProductionFile: File | null = null;
	let compareProductionFileName = '';

	let loading = false;
	let error = '';
	let baselines: any[] = [];
	let selectedBaselineId = '';
	let result: any = null;
	let baselineResult: any = null;
	let activeTab: 'overview' | 'features' | 'recommendations' = 'overview';

	// Load baselines on mount
	$: if (mode === 'analyze') {
		loadBaselines();
	}

	async function loadBaselines() {
		try {
			const response = await fetch(`${API_BASE}/drift/baselines`);
			if (response.ok) {
				const data = await response.json();
				baselines = data.baselines || [];
			}
		} catch (e) {
			console.error('Failed to load baselines:', e);
		}
	}

	function handleBaselineFileSelect(event: Event) {
		const input = event.target as HTMLInputElement;
		if (input.files && input.files[0]) {
			baselineFile = input.files[0];
			baselineFileName = baselineFile.name;
			baselineResult = null;
			error = '';
		}
	}

	function handleProductionFileSelect(event: Event) {
		const input = event.target as HTMLInputElement;
		if (input.files && input.files[0]) {
			productionFile = input.files[0];
			productionFileName = productionFile.name;
			result = null;
			error = '';
		}
	}

	function handleCompareBaselineSelect(event: Event) {
		const input = event.target as HTMLInputElement;
		if (input.files && input.files[0]) {
			compareBaselineFile = input.files[0];
			compareBaselineFileName = compareBaselineFile.name;
			result = null;
			error = '';
		}
	}

	function handleCompareProductionSelect(event: Event) {
		const input = event.target as HTMLInputElement;
		if (input.files && input.files[0]) {
			compareProductionFile = input.files[0];
			compareProductionFileName = compareProductionFile.name;
			result = null;
			error = '';
		}
	}

	function handleDrop(event: DragEvent, target: string) {
		event.preventDefault();
		if (event.dataTransfer?.files && event.dataTransfer.files[0]) {
			const file = event.dataTransfer.files[0];
			if (target === 'baseline') {
				baselineFile = file;
				baselineFileName = file.name;
			} else if (target === 'production') {
				productionFile = file;
				productionFileName = file.name;
			} else if (target === 'compare-baseline') {
				compareBaselineFile = file;
				compareBaselineFileName = file.name;
			} else if (target === 'compare-production') {
				compareProductionFile = file;
				compareProductionFileName = file.name;
			}
			result = null;
			error = '';
		}
	}

	function handleDragOver(event: DragEvent) {
		event.preventDefault();
	}

	async function uploadBaseline() {
		if (!baselineFile) {
			error = 'Please select a baseline file';
			return;
		}

		loading = true;
		error = '';
		baselineResult = null;

		try {
			const formData = new FormData();
			formData.append('file', baselineFile);
			if (baselineName) {
				formData.append('name', baselineName);
			}

			const response = await fetch(`${API_BASE}/drift/baseline`, {
				method: 'POST',
				body: formData
			});

			if (!response.ok) {
				const errData = await response.json();
				throw new Error(errData.detail || 'Upload failed');
			}

			baselineResult = await response.json();
			loadBaselines();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to upload baseline';
		} finally {
			loading = false;
		}
	}

	async function analyzeDrift() {
		if (!productionFile) {
			error = 'Please select a production file';
			return;
		}
		if (!selectedBaselineId) {
			error = 'Please select a baseline for comparison';
			return;
		}

		loading = true;
		error = '';
		result = null;

		try {
			const formData = new FormData();
			formData.append('production_file', productionFile);
			formData.append('baseline_id', selectedBaselineId);

			const response = await fetch(`${API_BASE}/drift/analyze`, {
				method: 'POST',
				body: formData
			});

			if (!response.ok) {
				const errData = await response.json();
				throw new Error(errData.detail || 'Analysis failed');
			}

			result = await response.json();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to analyze drift';
		} finally {
			loading = false;
		}
	}

	async function compareFiles() {
		if (!compareBaselineFile || !compareProductionFile) {
			error = 'Please select both baseline and production files';
			return;
		}

		loading = true;
		error = '';
		result = null;

		try {
			const formData = new FormData();
			formData.append('baseline_file', compareBaselineFile);
			formData.append('production_file', compareProductionFile);

			const response = await fetch(`${API_BASE}/drift/compare-files`, {
				method: 'POST',
				body: formData
			});

			if (!response.ok) {
				const errData = await response.json();
				throw new Error(errData.detail || 'Comparison failed');
			}

			result = await response.json();
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to compare files';
		} finally {
			loading = false;
		}
	}

	function getSeverityColor(severity: string): string {
		switch (severity) {
			case 'severe':
				return 'text-red-700 bg-red-50 border-red-200';
			case 'moderate':
				return 'text-orange-700 bg-orange-50 border-orange-200';
			case 'minor':
				return 'text-yellow-700 bg-yellow-50 border-yellow-200';
			default:
				return 'text-green-700 bg-green-50 border-green-200';
		}
	}

	function getSeverityBadgeColor(severity: string): string {
		switch (severity) {
			case 'severe':
				return 'bg-red-100 text-red-700';
			case 'moderate':
				return 'bg-orange-100 text-orange-700';
			case 'minor':
				return 'bg-yellow-100 text-yellow-700';
			default:
				return 'bg-green-100 text-green-700';
		}
	}

	function formatPSI(psi: number): string {
		if (psi >= 0.25) return 'Severe';
		if (psi >= 0.2) return 'Moderate';
		if (psi >= 0.1) return 'Minor';
		return 'Stable';
	}
</script>

<div class="max-w-6xl mx-auto animate-fade-in">
	<!-- Header -->
	<div class="mb-6">
		<h1 class="text-2xl font-bold text-surface-800">Model Drift Monitor</h1>
		<p class="text-surface-600 mt-1">Detect distribution shifts in your ML features using PSI and Kolmogorov-Smirnov tests</p>
	</div>

	<div class="grid grid-cols-1 lg:grid-cols-3 gap-4">
		<!-- Input Section -->
		<div class="card p-4">
			<h2 class="text-base font-bold text-surface-800 mb-3">Configuration</h2>

			<!-- Mode Toggle -->
			<div class="flex flex-col gap-1 mb-4 p-1 bg-surface-100 rounded-lg">
				<button
					class="py-2 px-3 text-sm font-medium rounded-md transition-all {mode === 'upload-baseline'
						? 'bg-white text-primary-600 shadow-sm'
						: 'text-surface-500 hover:text-surface-700'}"
					on:click={() => { mode = 'upload-baseline'; result = null; }}
				>
					1. Upload Baseline
				</button>
				<button
					class="py-2 px-3 text-sm font-medium rounded-md transition-all {mode === 'analyze'
						? 'bg-white text-primary-600 shadow-sm'
						: 'text-surface-500 hover:text-surface-700'}"
					on:click={() => { mode = 'analyze'; result = null; loadBaselines(); }}
				>
					2. Analyze vs Baseline
				</button>
				<button
					class="py-2 px-3 text-sm font-medium rounded-md transition-all {mode === 'compare'
						? 'bg-white text-primary-600 shadow-sm'
						: 'text-surface-500 hover:text-surface-700'}"
					on:click={() => { mode = 'compare'; result = null; }}
				>
					3. Quick Compare
				</button>
			</div>

			{#if mode === 'upload-baseline'}
				<div class="space-y-4">
					<div>
						<label class="label">Baseline Name (optional)</label>
						<input
							type="text"
							bind:value={baselineName}
							placeholder="e.g., Training Data v1.0"
							class="input"
						/>
					</div>

					<!-- Drop Zone for Baseline -->
					<div
						class="border-2 border-dashed border-surface-300 rounded-xl p-6 text-center hover:border-primary-400 transition-colors cursor-pointer"
						on:drop={(e) => handleDrop(e, 'baseline')}
						on:dragover={handleDragOver}
						role="button"
						tabindex="0"
					>
						<input
							type="file"
							accept=".csv,.json"
							on:change={handleBaselineFileSelect}
							class="hidden"
							id="baseline-input"
						/>
						<label for="baseline-input" class="cursor-pointer">
							<div class="w-12 h-12 rounded-xl bg-blue-100 flex items-center justify-center mx-auto mb-3">
								<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
									<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
								</svg>
							</div>
							<p class="text-sm text-surface-600">
								<span class="text-primary-600 font-medium">Upload baseline</span> dataset
							</p>
							<p class="text-xs text-surface-400 mt-1">CSV or JSON files</p>
						</label>
					</div>

					{#if baselineFileName}
						<div class="flex items-center gap-2 p-2 bg-surface-50 rounded-lg">
							<svg class="w-4 h-4 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
							</svg>
							<span class="text-sm text-surface-700 truncate flex-1">{baselineFileName}</span>
						</div>
					{/if}

					<button
						on:click={uploadBaseline}
						disabled={loading || !baselineFile}
						class="btn-primary w-full disabled:opacity-50"
					>
						{loading ? 'Uploading...' : 'Upload Baseline'}
					</button>

					{#if baselineResult}
						<div class="mt-4 p-3 bg-green-50 rounded-lg border border-green-200">
							<p class="text-sm text-green-700 font-medium">Baseline uploaded successfully!</p>
							<p class="text-xs text-green-600 mt-1">ID: {baselineResult.baseline_id}</p>
							<p class="text-xs text-green-600">Rows: {baselineResult.row_count}</p>
							<p class="text-xs text-green-600">Columns: {baselineResult.numeric_columns?.length || 0} numeric</p>
						</div>
					{/if}
				</div>

			{:else if mode === 'analyze'}
				<div class="space-y-4">
					<!-- Select Baseline -->
					<div>
						<label class="label">Select Baseline</label>
						{#if baselines.length > 0}
							<select bind:value={selectedBaselineId} class="input">
								<option value="">Choose a baseline...</option>
								{#each baselines as baseline}
									<option value={baseline.id}>{baseline.name} ({baseline.row_count} rows)</option>
								{/each}
							</select>
						{:else}
							<div class="p-3 bg-yellow-50 rounded-lg border border-yellow-200">
								<p class="text-xs text-yellow-700">No baselines found. Upload one first.</p>
							</div>
						{/if}
					</div>

					<!-- Drop Zone for Production -->
					<div
						class="border-2 border-dashed border-surface-300 rounded-xl p-6 text-center hover:border-primary-400 transition-colors cursor-pointer"
						on:drop={(e) => handleDrop(e, 'production')}
						on:dragover={handleDragOver}
						role="button"
						tabindex="0"
					>
						<input
							type="file"
							accept=".csv,.json"
							on:change={handleProductionFileSelect}
							class="hidden"
							id="production-input"
						/>
						<label for="production-input" class="cursor-pointer">
							<div class="w-12 h-12 rounded-xl bg-orange-100 flex items-center justify-center mx-auto mb-3">
								<svg class="w-6 h-6 text-orange-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
									<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
								</svg>
							</div>
							<p class="text-sm text-surface-600">
								<span class="text-primary-600 font-medium">Upload production</span> data
							</p>
							<p class="text-xs text-surface-400 mt-1">CSV or JSON files</p>
						</label>
					</div>

					{#if productionFileName}
						<div class="flex items-center gap-2 p-2 bg-surface-50 rounded-lg">
							<svg class="w-4 h-4 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
								<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
							</svg>
							<span class="text-sm text-surface-700 truncate flex-1">{productionFileName}</span>
						</div>
					{/if}

					<button
						on:click={analyzeDrift}
						disabled={loading || !productionFile || !selectedBaselineId}
						class="btn-primary w-full disabled:opacity-50"
					>
						{loading ? 'Analyzing...' : 'Analyze Drift'}
					</button>
				</div>

			{:else if mode === 'compare'}
				<div class="space-y-4">
					<p class="text-xs text-surface-600">Compare two files directly without storing a baseline.</p>

					<!-- Baseline File -->
					<div
						class="border-2 border-dashed border-surface-300 rounded-xl p-4 text-center hover:border-blue-400 transition-colors cursor-pointer"
						on:drop={(e) => handleDrop(e, 'compare-baseline')}
						on:dragover={handleDragOver}
						role="button"
						tabindex="0"
					>
						<input
							type="file"
							accept=".csv,.json"
							on:change={handleCompareBaselineSelect}
							class="hidden"
							id="compare-baseline-input"
						/>
						<label for="compare-baseline-input" class="cursor-pointer">
							<div class="w-8 h-8 rounded-lg bg-blue-100 flex items-center justify-center mx-auto mb-2">
								<span class="text-blue-600 font-bold text-sm">1</span>
							</div>
							<p class="text-xs text-surface-600">
								{compareBaselineFileName || 'Upload baseline file'}
							</p>
						</label>
					</div>

					<!-- Production File -->
					<div
						class="border-2 border-dashed border-surface-300 rounded-xl p-4 text-center hover:border-orange-400 transition-colors cursor-pointer"
						on:drop={(e) => handleDrop(e, 'compare-production')}
						on:dragover={handleDragOver}
						role="button"
						tabindex="0"
					>
						<input
							type="file"
							accept=".csv,.json"
							on:change={handleCompareProductionSelect}
							class="hidden"
							id="compare-production-input"
						/>
						<label for="compare-production-input" class="cursor-pointer">
							<div class="w-8 h-8 rounded-lg bg-orange-100 flex items-center justify-center mx-auto mb-2">
								<span class="text-orange-600 font-bold text-sm">2</span>
							</div>
							<p class="text-xs text-surface-600">
								{compareProductionFileName || 'Upload production file'}
							</p>
						</label>
					</div>

					<button
						on:click={compareFiles}
						disabled={loading || !compareBaselineFile || !compareProductionFile}
						class="btn-primary w-full disabled:opacity-50"
					>
						{loading ? 'Comparing...' : 'Compare Files'}
					</button>
				</div>
			{/if}

			{#if error}
				<div class="mt-3 p-2 bg-red-50 text-red-700 text-sm rounded-lg border border-red-100">
					{error}
				</div>
			{/if}
		</div>

		<!-- Results Section -->
		<div class="lg:col-span-2 card p-4">
			<h2 class="text-base font-bold text-surface-800 mb-3">Drift Analysis Results</h2>

			{#if result}
				<!-- Summary Cards -->
				<div class="grid grid-cols-4 gap-2 mb-4">
					<div class="bg-surface-50 rounded-lg p-3 text-center border border-surface-100">
						<p class="text-xs text-surface-600">Status</p>
						<p class="text-sm font-bold {result.is_drifted ? 'text-red-600' : 'text-green-600'}">
							{result.is_drifted ? 'Drift Detected' : 'Stable'}
						</p>
					</div>
					<div class="bg-surface-50 rounded-lg p-3 text-center border border-surface-100">
						<p class="text-xs text-surface-600">Avg PSI</p>
						<p class="text-lg font-bold text-surface-800">{result.overall_score?.toFixed(4)}</p>
					</div>
					<div class="bg-surface-50 rounded-lg p-3 text-center border border-surface-100">
						<p class="text-xs text-surface-600">Drifted</p>
						<p class="text-lg font-bold text-surface-800">{result.drifted_features}/{result.total_features}</p>
					</div>
					<div class="rounded-lg p-3 text-center border {getSeverityColor(result.drift_severity)}">
						<p class="text-xs opacity-80">Severity</p>
						<p class="text-sm font-bold capitalize">{result.drift_severity}</p>
					</div>
				</div>

				<!-- Tabs -->
				<div class="flex gap-1 mb-4 border-b border-surface-200">
					<button
						class="px-4 py-2 text-sm font-medium transition-colors {activeTab === 'overview'
							? 'text-primary-600 border-b-2 border-primary-600'
							: 'text-surface-500 hover:text-surface-700'}"
						on:click={() => (activeTab = 'overview')}
					>
						Overview
					</button>
					<button
						class="px-4 py-2 text-sm font-medium transition-colors {activeTab === 'features'
							? 'text-primary-600 border-b-2 border-primary-600'
							: 'text-surface-500 hover:text-surface-700'}"
						on:click={() => (activeTab = 'features')}
					>
						Features ({result.total_features})
					</button>
					<button
						class="px-4 py-2 text-sm font-medium transition-colors {activeTab === 'recommendations'
							? 'text-primary-600 border-b-2 border-primary-600'
							: 'text-surface-500 hover:text-surface-700'}"
						on:click={() => (activeTab = 'recommendations')}
					>
						Recommendations
					</button>
				</div>

				<!-- Tab Content -->
				{#if activeTab === 'overview'}
					<div class="space-y-3">
						<!-- Drift Summary by Severity -->
						<div class="bg-surface-50 rounded-lg p-4 border border-surface-100">
							<h3 class="text-sm font-semibold text-surface-700 mb-3">Drift Summary</h3>
							<div class="grid grid-cols-4 gap-2">
								<div class="text-center p-2 rounded-lg bg-red-50 border border-red-100">
									<p class="text-lg font-bold text-red-600">
										{result.feature_scores?.filter(f => f.drift_type === 'severe').length || 0}
									</p>
									<p class="text-xs text-red-600">Severe</p>
								</div>
								<div class="text-center p-2 rounded-lg bg-orange-50 border border-orange-100">
									<p class="text-lg font-bold text-orange-600">
										{result.feature_scores?.filter(f => f.drift_type === 'moderate').length || 0}
									</p>
									<p class="text-xs text-orange-600">Moderate</p>
								</div>
								<div class="text-center p-2 rounded-lg bg-yellow-50 border border-yellow-100">
									<p class="text-lg font-bold text-yellow-600">
										{result.feature_scores?.filter(f => f.drift_type === 'minor').length || 0}
									</p>
									<p class="text-xs text-yellow-600">Minor</p>
								</div>
								<div class="text-center p-2 rounded-lg bg-green-50 border border-green-100">
									<p class="text-lg font-bold text-green-600">
										{result.feature_scores?.filter(f => f.drift_type === 'none').length || 0}
									</p>
									<p class="text-xs text-green-600">Stable</p>
								</div>
							</div>
						</div>

						<!-- Method Info -->
						<div class="bg-blue-50 rounded-lg p-4 border border-blue-200">
							<h3 class="text-sm font-semibold text-blue-800 mb-2">Analysis Method</h3>
							<p class="text-sm text-blue-700">{result.method}</p>
							<div class="mt-2 text-xs text-blue-600 space-y-1">
								<p><strong>PSI (Population Stability Index):</strong> Measures distribution shift. PSI &gt; 0.2 indicates significant drift.</p>
								<p><strong>KS Test:</strong> Kolmogorov-Smirnov test for distribution difference. p-value &lt; 0.05 indicates drift.</p>
							</div>
						</div>

						<!-- Engine Badge -->
						<div class="flex items-center gap-2">
							<span class="text-xs px-2 py-1 bg-purple-100 text-purple-700 rounded">Engine: {result.engine}</span>
							<span class="text-xs text-surface-500">{result.timestamp}</span>
						</div>
					</div>

				{:else if activeTab === 'features'}
					<div class="overflow-x-auto">
						{#if result.feature_scores && result.feature_scores.length > 0}
							<table class="table-modern">
								<thead>
									<tr>
										<th>Feature</th>
										<th class="text-right">PSI</th>
										<th class="text-right">KS Stat</th>
										<th class="text-right">p-value</th>
										<th>Status</th>
									</tr>
								</thead>
								<tbody>
									{#each result.feature_scores as feature}
										<tr>
											<td class="font-medium">{feature.feature}</td>
											<td class="text-right font-mono text-sm">{feature.psi_score.toFixed(4)}</td>
											<td class="text-right font-mono text-sm">{feature.ks_statistic.toFixed(4)}</td>
											<td class="text-right font-mono text-sm">{feature.ks_pvalue.toFixed(4)}</td>
											<td>
												<span class="text-xs px-2 py-1 rounded capitalize {getSeverityBadgeColor(feature.drift_type)}">
													{feature.drift_type}
												</span>
											</td>
										</tr>
									{/each}
								</tbody>
							</table>
						{:else}
							<div class="text-center py-8 text-surface-500">
								No feature data available
							</div>
						{/if}
					</div>

				{:else if activeTab === 'recommendations'}
					<div class="space-y-2">
						{#if result.recommendations && result.recommendations.length > 0}
							{#each result.recommendations as rec}
								<div class="p-3 rounded-lg border {rec.includes('CRITICAL')
									? 'bg-red-50 border-red-200'
									: rec.includes('WARNING')
										? 'bg-orange-50 border-orange-200'
										: rec.includes('INFO')
											? 'bg-blue-50 border-blue-200'
											: rec.includes('No significant drift')
												? 'bg-green-50 border-green-200'
												: 'bg-surface-50 border-surface-200'}">
									<p class="text-sm">{rec}</p>
								</div>
							{/each}
						{:else}
							<div class="text-center py-8 text-surface-500">
								No recommendations available
							</div>
						{/if}
					</div>
				{/if}

			{:else}
				<div class="text-center py-12">
					<div class="w-16 h-16 rounded-2xl bg-surface-100 flex items-center justify-center mx-auto mb-4">
						<svg class="w-8 h-8 text-surface-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
							<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
						</svg>
					</div>
					<p class="text-surface-500 mb-2">Upload a baseline first, then compare with production data</p>
					<p class="text-xs text-surface-400">Or use Quick Compare to analyze two files directly</p>
				</div>
			{/if}
		</div>
	</div>
</div>
