<script lang="ts">
	import { page } from '$app/stores';
	import type { Stage, StageEnv } from '$lib/types';
	import * as api from '$lib/api';
	import { toasts } from '$lib/stores/toast';

	let stages = $state<Stage[]>([]);
	let selectedStageId = $state('');
	let envVars = $state<StageEnv[]>([]);
	let projectEnv = $state<Record<string, string>>({});
	let loading = $state(true);
	let envLoading = $state(false);
	let error = $state('');

	// New env var form.
	let newKey = $state('');
	let newValue = $state('');
	let newEncrypted = $state(false);
	let saving = $state(false);

	// Edit state.
	let editingId = $state('');
	let editKey = $state('');
	let editValue = $state('');
	let editEncrypted = $state(false);

	const projectId = $derived($page.params.id);

	async function loadProject() {
		loading = true;
		error = '';
		try {
			const detail = await api.getProject(projectId);
			stages = detail.stages;

			// Parse project-level env.
			try {
				projectEnv = JSON.parse(detail.project.env || '{}');
			} catch {
				projectEnv = {};
			}

			if (stages.length > 0 && !selectedStageId) {
				selectedStageId = stages[0].id;
			}
		} catch (e) {
			error = e instanceof Error ? e.message : 'Failed to load project';
		} finally {
			loading = false;
		}
	}

	async function loadStageEnv(stageId: string) {
		if (!stageId) return;
		envLoading = true;
		try {
			envVars = await api.listStageEnv(projectId, stageId);
		} catch (e) {
			toasts.error(e instanceof Error ? e.message : 'Failed to load env vars');
			envVars = [];
		} finally {
			envLoading = false;
		}
	}

	async function handleAdd() {
		if (!newKey.trim() || !selectedStageId) return;
		saving = true;
		try {
			await api.createStageEnv(projectId, selectedStageId, {
				key: newKey.trim(),
				value: newValue,
				encrypted: newEncrypted
			});
			newKey = '';
			newValue = '';
			newEncrypted = false;
			toasts.success('Environment variable added');
			await loadStageEnv(selectedStageId);
		} catch (e) {
			toasts.error(e instanceof Error ? e.message : 'Failed to add env var');
		} finally {
			saving = false;
		}
	}

	function startEdit(env: StageEnv) {
		editingId = env.id;
		editKey = env.key;
		editValue = env.encrypted ? '' : env.value;
		editEncrypted = env.encrypted;
	}

	function cancelEdit() {
		editingId = '';
	}

	async function handleUpdate() {
		if (!editKey.trim()) return;
		saving = true;
		try {
			const data: { key?: string; value?: string; encrypted?: boolean } = {
				key: editKey.trim(),
				encrypted: editEncrypted
			};
			if (editValue) {
				data.value = editValue;
			}
			await api.updateStageEnv(projectId, selectedStageId, editingId, data);
			editingId = '';
			toasts.success('Environment variable updated');
			await loadStageEnv(selectedStageId);
		} catch (e) {
			toasts.error(e instanceof Error ? e.message : 'Failed to update env var');
		} finally {
			saving = false;
		}
	}

	async function handleDelete(envId: string) {
		try {
			await api.deleteStageEnv(projectId, selectedStageId, envId);
			toasts.success('Environment variable deleted');
			await loadStageEnv(selectedStageId);
		} catch (e) {
			toasts.error(e instanceof Error ? e.message : 'Failed to delete env var');
		}
	}

	// Determine if a key is inherited from project level.
	function isInherited(key: string): boolean {
		return key in projectEnv;
	}

	// Determine if a key is overridden at stage level.
	function isOverridden(key: string): boolean {
		return envVars.some((e) => e.key === key);
	}

	$effect(() => {
		void projectId;
		loadProject();
	});

	$effect(() => {
		if (selectedStageId) {
			loadStageEnv(selectedStageId);
		}
	});
</script>

<svelte:head>
	<title>Environment Variables - Docker Watcher</title>
</svelte:head>

<div>
	<!-- Header -->
	<div class="flex items-center gap-2">
		<a href="/projects/{projectId}" class="text-sm text-gray-500 hover:text-gray-700">Project</a>
		<span class="text-sm text-gray-400">/</span>
		<h1 class="text-2xl font-bold text-gray-900">Environment Variables</h1>
	</div>
	<p class="mt-1 text-sm text-gray-500">
		Manage per-stage environment variable overrides. Stage-level values override project-level defaults.
	</p>

	{#if loading}
		<div class="mt-8 flex items-center justify-center py-12">
			<div class="h-8 w-8 animate-spin rounded-full border-4 border-gray-200 border-t-indigo-600"></div>
		</div>
	{:else if error}
		<div class="mt-4 rounded-md bg-red-50 p-4">
			<p class="text-sm text-red-700">{error}</p>
		</div>
	{:else}
		<!-- Stage selector -->
		<div class="mt-6">
			<label for="stage-select" class="block text-sm font-medium text-gray-700">Stage</label>
			<select
				id="stage-select"
				bind:value={selectedStageId}
				class="mt-1 block w-64 rounded-md border border-gray-300 bg-white px-3 py-2 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500 focus:outline-none"
			>
				{#each stages as stage (stage.id)}
					<option value={stage.id}>{stage.name}</option>
				{/each}
			</select>
		</div>

		{#if stages.length === 0}
			<div class="mt-6 rounded-lg border-2 border-dashed border-gray-300 p-8 text-center">
				<p class="text-sm text-gray-500">No stages configured. Add stages to the project first.</p>
			</div>
		{:else}
			<!-- Project-level env (read-only reference) -->
			{#if Object.keys(projectEnv).length > 0}
				<div class="mt-6">
					<h2 class="text-sm font-semibold text-gray-700">Project-Level Defaults</h2>
					<div class="mt-2 rounded-lg border border-gray-200 bg-gray-50">
						<table class="min-w-full divide-y divide-gray-200">
							<thead>
								<tr>
									<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Key</th>
									<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Value</th>
									<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Status</th>
								</tr>
							</thead>
							<tbody class="divide-y divide-gray-200">
								{#each Object.entries(projectEnv) as [key, value] (key)}
									<tr class={isOverridden(key) ? 'opacity-50' : ''}>
										<td class="whitespace-nowrap px-4 py-2 font-mono text-sm text-gray-900">{key}</td>
										<td class="px-4 py-2 font-mono text-sm text-gray-600">{value}</td>
										<td class="px-4 py-2 text-sm">
											{#if isOverridden(key)}
												<span class="rounded bg-yellow-50 px-2 py-0.5 text-xs font-medium text-yellow-700">
													overridden
												</span>
											{:else}
												<span class="rounded bg-green-50 px-2 py-0.5 text-xs font-medium text-green-700">
													inherited
												</span>
											{/if}
										</td>
									</tr>
								{/each}
							</tbody>
						</table>
					</div>
				</div>
			{/if}

			<!-- Stage-level overrides -->
			<div class="mt-6">
				<h2 class="text-sm font-semibold text-gray-700">Stage Overrides</h2>

				{#if envLoading}
					<div class="mt-4 flex items-center justify-center py-8">
						<div class="h-6 w-6 animate-spin rounded-full border-4 border-gray-200 border-t-indigo-600"></div>
					</div>
				{:else}
					<div class="mt-2 rounded-lg border border-gray-200 bg-white shadow-sm">
						<table class="min-w-full divide-y divide-gray-200">
							<thead class="bg-gray-50">
								<tr>
									<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Key</th>
									<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Value</th>
									<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Secret</th>
									<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Source</th>
									<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase">Actions</th>
								</tr>
							</thead>
							<tbody class="divide-y divide-gray-200">
								{#each envVars as env (env.id)}
									{#if editingId === env.id}
										<tr class="bg-indigo-50">
											<td class="px-4 py-2">
												<input
													type="text"
													bind:value={editKey}
													class="block w-full rounded-md border border-gray-300 px-2 py-1 font-mono text-sm focus:border-indigo-500 focus:ring-indigo-500 focus:outline-none"
												/>
											</td>
											<td class="px-4 py-2">
												<input
													type={editEncrypted ? 'password' : 'text'}
													bind:value={editValue}
													placeholder={env.encrypted ? 'Leave empty to keep current' : ''}
													class="block w-full rounded-md border border-gray-300 px-2 py-1 font-mono text-sm focus:border-indigo-500 focus:ring-indigo-500 focus:outline-none"
												/>
											</td>
											<td class="px-4 py-2">
												<input type="checkbox" bind:checked={editEncrypted} class="rounded" />
											</td>
											<td class="px-4 py-2"></td>
											<td class="px-4 py-2 text-right">
												<button
													type="button"
													class="mr-2 text-sm font-medium text-indigo-600 hover:text-indigo-800"
													disabled={saving}
													onclick={handleUpdate}
												>
													Save
												</button>
												<button
													type="button"
													class="text-sm text-gray-500 hover:text-gray-700"
													onclick={cancelEdit}
												>
													Cancel
												</button>
											</td>
										</tr>
									{:else}
										<tr>
											<td class="whitespace-nowrap px-4 py-2 font-mono text-sm text-gray-900">{env.key}</td>
											<td class="px-4 py-2 font-mono text-sm text-gray-600">
												{env.encrypted ? '••••••••' : env.value}
											</td>
											<td class="px-4 py-2">
												{#if env.encrypted}
													<span class="rounded bg-purple-50 px-2 py-0.5 text-xs font-medium text-purple-700">
														secret
													</span>
												{/if}
											</td>
											<td class="px-4 py-2 text-sm">
												{#if isInherited(env.key)}
													<span class="rounded bg-yellow-50 px-2 py-0.5 text-xs font-medium text-yellow-700">
														overrides project
													</span>
												{:else}
													<span class="rounded bg-blue-50 px-2 py-0.5 text-xs font-medium text-blue-700">
														stage only
													</span>
												{/if}
											</td>
											<td class="whitespace-nowrap px-4 py-2 text-right">
												<button
													type="button"
													class="mr-2 text-sm font-medium text-indigo-600 hover:text-indigo-800"
													onclick={() => startEdit(env)}
												>
													{env.encrypted ? 'Change' : 'Edit'}
												</button>
												<button
													type="button"
													class="text-sm font-medium text-red-600 hover:text-red-800"
													onclick={() => handleDelete(env.id)}
												>
													Delete
												</button>
											</td>
										</tr>
									{/if}
								{/each}

								<!-- Add new row -->
								<tr class="bg-gray-50">
									<td class="px-4 py-2">
										<input
											type="text"
											bind:value={newKey}
											placeholder="KEY_NAME"
											class="block w-full rounded-md border border-gray-300 px-2 py-1 font-mono text-sm focus:border-indigo-500 focus:ring-indigo-500 focus:outline-none"
										/>
									</td>
									<td class="px-4 py-2">
										<input
											type={newEncrypted ? 'password' : 'text'}
											bind:value={newValue}
											placeholder="value"
											class="block w-full rounded-md border border-gray-300 px-2 py-1 font-mono text-sm focus:border-indigo-500 focus:ring-indigo-500 focus:outline-none"
										/>
									</td>
									<td class="px-4 py-2">
										<label class="flex items-center gap-1 text-xs text-gray-600">
											<input type="checkbox" bind:checked={newEncrypted} class="rounded" />
											Secret
										</label>
									</td>
									<td class="px-4 py-2"></td>
									<td class="px-4 py-2 text-right">
										<button
											type="button"
											class="rounded-md bg-indigo-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-indigo-700 disabled:opacity-50"
											disabled={!newKey.trim() || saving}
											onclick={handleAdd}
										>
											{saving ? 'Adding...' : 'Add'}
										</button>
									</td>
								</tr>
							</tbody>
						</table>
					</div>
				{/if}
			</div>
		{/if}
	{/if}
</div>
