<script lang="ts">
	import { page } from '$app/stores';
	import type { Volume, VolumeScope, VolumeScopeInfo } from '$lib/types';
	import * as api from '$lib/api';
	import { toasts } from '$lib/stores/toast';
	import { t } from '$lib/i18n';
	import { IconChevronRight, IconPlus, IconEdit, IconTrash, IconCheck, IconX, IconSearch, IconExternalLink } from '$lib/components/icons';
	import Skeleton from '$lib/components/Skeleton.svelte';

	function downloadUrl(volId: string): string {
		return api.volumeDownloadUrl(projectId, volId);
	}

	let volumes = $state<Volume[]>([]);
	let scopeInfos = $state<VolumeScopeInfo[]>([]);
	let loading = $state(true);
	let error = $state('');

	let newSource = $state('');
	let newTarget = $state('');
	let newScope = $state<VolumeScope>('project');
	let newName = $state('');
	let saving = $state(false);

	let editingId = $state('');
	let editSource = $state('');
	let editTarget = $state('');
	let editScope = $state<VolumeScope>('project');
	let editName = $state('');

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

	const newNeedsName = $derived(newScope === 'project_named' || newScope === 'named');
	const editNeedsName = $derived(editScope === 'project_named' || editScope === 'named');
	const newIsEphemeral = $derived(newScope === 'ephemeral');
	const editIsEphemeral = $derived(editScope === 'ephemeral');

	function scopeDescription(scope: VolumeScope): string {
		return scopeInfos.find(s => s.scope === scope)?.description ?? '';
	}

	function scopePathExample(scope: VolumeScope): string {
		return scopeInfos.find(s => s.scope === scope)?.path_example ?? '';
	}

	const scopeColors: Record<string, { bg: string; text: string }> = {
		instance: { bg: 'bg-amber-50 dark:bg-amber-900/30', text: 'text-amber-700 dark:text-amber-400' },
		stage: { bg: 'bg-blue-50 dark:bg-blue-900/30', text: 'text-blue-700 dark:text-blue-400' },
		project: { bg: 'bg-emerald-50 dark:bg-emerald-900/30', text: 'text-emerald-700 dark:text-emerald-400' },
		project_named: { bg: 'bg-violet-50 dark:bg-violet-900/30', text: 'text-violet-700 dark:text-violet-400' },
		named: { bg: 'bg-purple-50 dark:bg-purple-900/30', text: 'text-purple-700 dark:text-purple-400' },
		ephemeral: { bg: 'bg-gray-100 dark:bg-gray-800', text: 'text-gray-600 dark:text-gray-400' },
	};

	function scopeColor(scope: string) {
		return scopeColors[scope] ?? scopeColors.project;
	}

	async function loadData() {
		loading = true;
		error = '';
		try {
			const [vols, scopes] = await Promise.all([
				api.listVolumes(projectId),
				api.listVolumeScopes()
			]);
			volumes = vols;
			scopeInfos = scopes;
		} catch (e) {
			error = e instanceof Error ? e.message : $t('volumeEditor.loadFailed');
		} finally {
			loading = false;
		}
	}

	async function handleAdd() {
		if (!newIsEphemeral && !newSource.trim()) return;
		if (!newTarget.trim()) return;
		if (newNeedsName && !newName.trim()) return;
		saving = true;
		try {
			await api.createVolume(projectId, {
				source: newSource.trim(),
				target: newTarget.trim(),
				scope: newScope,
				name: newNeedsName ? newName.trim() : undefined
			});
			newSource = '';
			newTarget = '';
			newScope = 'project';
			newName = '';
			toasts.success($t('volumeEditor.volumeAdded'));
			await loadData();
		} catch (e) {
			toasts.error(e instanceof Error ? e.message : $t('volumeEditor.addFailed'));
		} finally {
			saving = false;
		}
	}

	function startEdit(vol: Volume) {
		editingId = vol.id;
		editSource = vol.source;
		editTarget = vol.target;
		editScope = vol.scope || 'project';
		editName = vol.name || '';
	}

	function cancelEdit() { editingId = ''; }

	async function handleUpdate() {
		if (!editIsEphemeral && !editSource.trim()) return;
		if (!editTarget.trim()) return;
		if (editNeedsName && !editName.trim()) return;
		saving = true;
		try {
			await api.updateVolume(projectId, editingId, {
				source: editSource.trim(),
				target: editTarget.trim(),
				scope: editScope,
				name: editNeedsName ? editName.trim() : ''
			});
			editingId = '';
			toasts.success($t('volumeEditor.volumeUpdated'));
			await loadData();
		} catch (e) {
			toasts.error(e instanceof Error ? e.message : $t('volumeEditor.updateFailed'));
		} finally {
			saving = false;
		}
	}

	async function handleDelete(volId: string) {
		try {
			await api.deleteVolume(projectId, volId);
			toasts.success($t('volumeEditor.volumeDeleted'));
			await loadData();
		} catch (e) {
			toasts.error(e instanceof Error ? e.message : $t('volumeEditor.deleteFailed'));
		}
	}

	$effect(() => {
		void projectId;
		loadData();
	});
</script>

<svelte:head>
	<title>{$t('volumeEditor.title')} - {$t('app.name')}</title>
</svelte:head>

<div class="space-y-6">
	<!-- Header -->
	<div>
		<div class="flex items-center gap-1.5 text-sm text-[var(--text-tertiary)]">
			<a href="/projects/{projectId}" class="hover:text-[var(--text-link)] transition-colors">{$t('common.project')}</a>
			<IconChevronRight size={14} />
		</div>
		<h1 class="mt-1 text-2xl font-bold text-[var(--text-primary)]">{$t('volumeEditor.title')}</h1>
		<p class="mt-1 text-sm text-[var(--text-secondary)]">{$t('volumeEditor.description')}</p>
	</div>

	<!-- Scope guide -->
	{#if scopeInfos.length > 0}
		<div class="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
			{#each scopeInfos as info}
				{@const colors = scopeColor(info.scope)}
				<div class="rounded-lg border border-[var(--border-primary)] p-3 {colors.bg}">
					<div class="flex items-center gap-2">
						<span class="rounded-full px-2 py-0.5 text-xs font-semibold {colors.text} {colors.bg}">{info.scope}</span>
						{#if info.needs_name}
							<span class="text-[10px] text-[var(--text-tertiary)]">({$t('volumeEditor.requiresName')})</span>
						{/if}
					</div>
					<p class="mt-1.5 text-xs text-[var(--text-secondary)]">{info.description}</p>
					<code class="mt-1 block text-[10px] text-[var(--text-tertiary)]">{info.path_example}</code>
				</div>
			{/each}
		</div>
	{/if}

	{#if loading}
		<Skeleton height="12rem" />
	{:else if error}
		<div class="rounded-xl border border-[var(--color-danger-light)] bg-[var(--color-danger-light)] p-4">
			<p class="text-sm text-[var(--color-danger)]">{error}</p>
			<button type="button" class="mt-2 text-sm font-medium text-[var(--color-danger)] underline hover:no-underline" onclick={loadData}>
				{$t('common.retry')}
			</button>
		</div>
	{:else}
		<!-- Volumes table -->
		<div class="overflow-hidden rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] shadow-[var(--shadow-sm)]">
			<table class="min-w-full divide-y divide-[var(--border-primary)]">
				<thead class="bg-[var(--surface-card-hover)]">
					<tr>
						<th class="px-4 py-3 text-left text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('volumeEditor.sourceHost')}</th>
						<th class="px-4 py-3 text-left text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('volumeEditor.targetContainer')}</th>
						<th class="px-4 py-3 text-left text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('volumeEditor.scope')}</th>
						<th class="px-4 py-3 text-left text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('volumeEditor.nameColumn')}</th>
						<th class="px-4 py-3 text-right text-xs font-medium text-[var(--text-tertiary)] uppercase">{$t('volumeEditor.actions')}</th>
					</tr>
				</thead>
				<tbody class="divide-y divide-[var(--border-secondary)]">
					{#each volumes as vol (vol.id)}
						{#if editingId === vol.id}
							<!-- Edit row -->
							<tr class="bg-[var(--color-brand-50)]/30">
								<td class="px-4 py-2.5">
									{#if editIsEphemeral}
										<span class="text-xs text-[var(--text-tertiary)] italic">{$t('volumeEditor.noHostPath')}</span>
									{:else}
										<input type="text" bind:value={editSource} class="block w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-2 py-1 font-mono text-sm focus:border-[var(--color-brand-500)] focus:ring-1 focus:ring-[var(--color-brand-500)] focus:outline-none" />
									{/if}
								</td>
								<td class="px-4 py-2.5">
									<input type="text" bind:value={editTarget} class="block w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-2 py-1 font-mono text-sm focus:border-[var(--color-brand-500)] focus:ring-1 focus:ring-[var(--color-brand-500)] focus:outline-none" />
								</td>
								<td class="px-4 py-2.5">
									<select bind:value={editScope} class="rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-2 py-1 text-sm focus:border-[var(--color-brand-500)] focus:ring-1 focus:ring-[var(--color-brand-500)] focus:outline-none">
										{#each scopeInfos as info}
											<option value={info.scope}>{info.scope}</option>
										{/each}
									</select>
								</td>
								<td class="px-4 py-2.5">
									{#if editNeedsName}
										<input type="text" bind:value={editName} placeholder={$t('volumeEditor.namePlaceholder')} class="block w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-2 py-1 text-sm focus:border-[var(--color-brand-500)] focus:ring-1 focus:ring-[var(--color-brand-500)] focus:outline-none" />
									{:else}
										<span class="text-xs text-[var(--text-tertiary)]">—</span>
									{/if}
								</td>
								<td class="px-4 py-2.5 text-right">
									<div class="flex items-center justify-end gap-1">
										<button type="button" class="rounded-lg p-1.5 text-emerald-600 hover:bg-emerald-50 transition-colors" disabled={saving} onclick={handleUpdate}><IconCheck size={16} /></button>
										<button type="button" class="rounded-lg p-1.5 text-[var(--text-tertiary)] hover:bg-[var(--surface-card-hover)] transition-colors" onclick={cancelEdit}><IconX size={16} /></button>
									</div>
								</td>
							</tr>
						{:else}
							<!-- Display row -->
							<tr class="hover:bg-[var(--surface-card-hover)] transition-colors">
								<td class="px-4 py-2.5 font-mono text-sm text-[var(--text-primary)]">
									{#if vol.scope === 'ephemeral'}
										<span class="text-xs text-[var(--text-tertiary)] italic">{$t('volumeEditor.tmpfs')}</span>
									{:else}
										{vol.source}
									{/if}
								</td>
								<td class="px-4 py-2.5 font-mono text-sm text-[var(--text-secondary)]">{vol.target}</td>
								<td class="px-4 py-2.5">
									<span class="rounded-full px-2 py-0.5 text-xs font-medium {scopeColor(vol.scope).bg} {scopeColor(vol.scope).text}">{vol.scope}</span>
								</td>
								<td class="px-4 py-2.5 text-sm text-[var(--text-secondary)]">
									{vol.name || '—'}
								</td>
								<td class="whitespace-nowrap px-4 py-2.5 text-right">
									<div class="flex items-center justify-end gap-1">
										{#if vol.scope !== 'ephemeral'}
											<a href="/projects/{projectId}/volumes/{vol.id}/browse" class="rounded-lg p-1.5 text-[var(--text-tertiary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-link)] transition-colors" title={$t('volumeBrowser.browse')}>
												<IconSearch size={16} />
											</a>
											<a href={downloadUrl(vol.id)} target="_blank" class="rounded-lg p-1.5 text-[var(--text-tertiary)] hover:bg-emerald-50 hover:text-emerald-600 transition-colors" title={$t('volumeBrowser.download')}>
												<IconExternalLink size={16} />
											</a>
										{/if}
										<button type="button" class="rounded-lg p-1.5 text-[var(--text-tertiary)] hover:bg-[var(--surface-card-hover)] hover:text-[var(--text-link)] transition-colors" onclick={() => startEdit(vol)}><IconEdit size={16} /></button>
										<button type="button" class="rounded-lg p-1.5 text-[var(--text-tertiary)] hover:bg-red-50 hover:text-red-600 transition-colors" onclick={() => handleDelete(vol.id)}><IconTrash size={16} /></button>
									</div>
								</td>
							</tr>
						{/if}
					{/each}

					<!-- Add new row -->
					<tr class="bg-[var(--surface-card-hover)]">
						<td class="px-4 py-2.5">
							{#if newIsEphemeral}
								<span class="text-xs text-[var(--text-tertiary)] italic">{$t('volumeEditor.noHostPath')}</span>
							{:else}
								<input type="text" bind:value={newSource} placeholder="/data/my-app/uploads" class="block w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-2 py-1 font-mono text-sm focus:border-[var(--color-brand-500)] focus:ring-1 focus:ring-[var(--color-brand-500)] focus:outline-none" />
							{/if}
						</td>
						<td class="px-4 py-2.5">
							<input type="text" bind:value={newTarget} placeholder="/app/uploads" class="block w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-2 py-1 font-mono text-sm focus:border-[var(--color-brand-500)] focus:ring-1 focus:ring-[var(--color-brand-500)] focus:outline-none" />
						</td>
						<td class="px-4 py-2.5">
							<select bind:value={newScope} class="rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-2 py-1 text-sm focus:border-[var(--color-brand-500)] focus:ring-1 focus:ring-[var(--color-brand-500)] focus:outline-none">
								{#each scopeInfos as info}
									<option value={info.scope}>{info.scope}</option>
								{/each}
							</select>
						</td>
						<td class="px-4 py-2.5">
							{#if newNeedsName}
								<input type="text" bind:value={newName} placeholder={$t('volumeEditor.namePlaceholder')} class="block w-full rounded-lg border border-[var(--border-input)] bg-[var(--surface-input)] px-2 py-1 text-sm focus:border-[var(--color-brand-500)] focus:ring-1 focus:ring-[var(--color-brand-500)] focus:outline-none" />
							{:else}
								<span class="text-xs text-[var(--text-tertiary)]">—</span>
							{/if}
						</td>
						<td class="px-4 py-2.5 text-right">
							<button
								type="button"
								class="inline-flex items-center gap-1 rounded-lg bg-[var(--color-brand-600)] px-3 py-1.5 text-xs font-medium text-white hover:bg-[var(--color-brand-700)] disabled:opacity-50 transition-colors active:animate-press"
								disabled={(!newIsEphemeral && !newSource.trim()) || !newTarget.trim() || (newNeedsName && !newName.trim()) || saving}
								onclick={handleAdd}
							>
								<IconPlus size={14} />
								{saving ? $t('volumeEditor.adding') : $t('volumeEditor.add')}
							</button>
						</td>
					</tr>
				</tbody>
			</table>
		</div>

		<!-- Scope hint for current selection -->
		{#if scopeDescription(newScope)}
			<div class="rounded-lg border border-[var(--border-primary)] bg-[var(--surface-card)] p-3">
				<p class="text-xs text-[var(--text-secondary)]">
					<strong class="text-[var(--text-primary)]">{newScope}:</strong>
					{scopeDescription(newScope)}
				</p>
				<code class="mt-1 block text-[10px] text-[var(--text-tertiary)]">{scopePathExample(newScope)}</code>
			</div>
		{/if}

		{#if volumes.length === 0}
			<p class="text-center text-sm text-[var(--text-tertiary)]">{$t('volumeEditor.noVolumes')}</p>
		{/if}
	{/if}
</div>
