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

	let volumes = $state<Volume[]>([]);
	let scopes = $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('');

	let volumeDeleteTarget = $state<string | null>(null);

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

	const newScopeNeedsName = $derived(scopes.find(s => s.scope === newScope)?.needs_name ?? false);
	const editScopeNeedsName = $derived(scopes.find(s => s.scope === editScope)?.needs_name ?? false);
	const newScopeIsEphemeral = $derived(newScope === 'ephemeral');
	const editScopeIsEphemeral = $derived(editScope === 'ephemeral');

	function scopeColor(scope: string): string {
		switch (scope) {
			case 'instance': return 'bg-amber-50 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400';
			case 'stage': return 'bg-cyan-50 text-cyan-700 dark:bg-cyan-900/30 dark:text-cyan-400';
			case 'project': return 'bg-blue-50 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400';
			case 'project_named': return 'bg-indigo-50 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400';
			case 'named': return 'bg-purple-50 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400';
			case 'ephemeral': return 'bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400';
			case 'absolute': return 'bg-rose-50 text-rose-700 dark:bg-rose-900/30 dark:text-rose-400';
			default: return 'bg-gray-100 text-gray-600';
		}
	}

	function scopeLabel(scope: string): string {
		return scope.replaceAll('_', ' ');
	}

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

	async function handleAdd() {
		if (newScope !== 'ephemeral' && !newSource.trim()) return;
		if (!newTarget.trim()) return;
		if (newScopeNeedsName && !newName.trim()) return;
		saving = true;
		try {
			await api.createVolume(projectId, {
				source: newSource.trim(),
				target: newTarget.trim(),
				scope: newScope,
				name: newScopeNeedsName ? newName.trim() : undefined
			});
			newSource = '';
			newTarget = '';
			newScope = 'project';
			newName = '';
			toasts.success($t('volumeEditor.volumeAdded'));
			await loadVolumes();
		} 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') as VolumeScope;
		editName = vol.name || '';
	}

	function cancelEdit() { editingId = ''; }

	async function handleUpdate() {
		if (editScope !== 'ephemeral' && !editSource.trim()) return;
		if (!editTarget.trim()) return;
		if (editScopeNeedsName && !editName.trim()) return;
		saving = true;
		try {
			await api.updateVolume(projectId, editingId, {
				source: editSource.trim(),
				target: editTarget.trim(),
				scope: editScope,
				name: editScopeNeedsName ? editName.trim() : undefined
			});
			editingId = '';
			toasts.success($t('volumeEditor.volumeUpdated'));
			await loadVolumes();
		} 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 loadVolumes();
		} catch (e) {
			toasts.error(e instanceof Error ? e.message : $t('volumeEditor.deleteFailed'));
		}
	}

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

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

<div class="space-y-6">
	<!-- Header -->
	<div>
		<Breadcrumb items={[{ label: $t('common.project'), href: `/projects/${projectId}` }]} />
		<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 legend -->
	{#if scopes.length > 0 && !loading}
		<div class="rounded-xl border border-[var(--border-primary)] bg-[var(--surface-card)] p-4 shadow-[var(--shadow-sm)]">
			<div class="flex items-center gap-2 mb-3">
				<IconInfo size={16} class="text-[var(--text-tertiary)]" />
				<h3 class="text-sm font-semibold text-[var(--text-primary)]">{$t('volumeEditor.scopeGuide')}</h3>
			</div>
			<div class="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3">
				{#each scopes as scope}
					<div class="flex items-start gap-2 rounded-lg bg-[var(--surface-card-hover)] px-3 py-2">
						<span class="mt-0.5 inline-flex shrink-0 items-center rounded-full px-2 py-0.5 text-xs font-medium {scopeColor(scope.scope)}">{scopeLabel(scope.scope)}</span>
						<div class="min-w-0">
							<p class="text-xs text-[var(--text-secondary)]">{scope.description}</p>
							<p class="mt-0.5 font-mono text-[10px] text-[var(--text-tertiary)]">{scope.path_example}</p>
						</div>
					</div>
				{/each}
			</div>
		</div>
	{/if}

	{#if loading}
		<div class="space-y-4">
			<Skeleton height="12rem" />
		</div>
	{: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={loadVolumes}>
				{$t('common.retry')}
			</button>
		</div>
	{:else}
		<div class="overflow-x-auto 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}
							<tr class="bg-[var(--color-brand-50)]/30">
								<td class="px-4 py-2.5">
									{#if editScopeIsEphemeral}
										<span class="text-xs italic text-[var(--text-tertiary)]">{$t('volumeEditor.tmpfs')}</span>
									{:else}
										<input type="text" bind:value={editSource} placeholder={editScope === 'absolute' ? '/mnt/data' : '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={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 scopes as s}
											<option value={s.scope}>{scopeLabel(s.scope)}</option>
										{/each}
									</select>
								</td>
								<td class="px-4 py-2.5">
									{#if editScopeNeedsName}
										<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 font-mono 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}
							<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="italic text-[var(--text-tertiary)]">{$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="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium {scopeColor(vol.scope)}">{scopeLabel(vol.scope)}</span>
								</td>
								<td class="px-4 py-2.5 font-mono 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">
										<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={() => { volumeDeleteTarget = vol.id; }} title={$t('common.delete')} aria-label={$t('common.delete')}><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 newScopeIsEphemeral}
								<span class="text-xs italic text-[var(--text-tertiary)]">{$t('volumeEditor.tmpfs')}</span>
							{:else}
								<input type="text" bind:value={newSource} placeholder={newScope === 'absolute' ? '/mnt/nfs/data' : '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 scopes as s}
									<option value={s.scope}>{scopeLabel(s.scope)}</option>
								{/each}
							</select>
						</td>
						<td class="px-4 py-2.5">
							{#if newScopeNeedsName}
								<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 font-mono 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={(!newScopeIsEphemeral && !newSource.trim()) || !newTarget.trim() || (newScopeNeedsName && !newName.trim()) || saving}
								onclick={handleAdd}
							>
								<IconPlus size={14} />
								{saving ? $t('volumeEditor.adding') : $t('volumeEditor.add')}
							</button>
						</td>
					</tr>
				</tbody>
			</table>
		</div>

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

<ConfirmDialog
	open={volumeDeleteTarget !== null}
	title={$t('volumeEditor.deleteTitle')}
	message={$t('volumeEditor.deleteMessage')}
	confirmLabel={$t('common.delete')}
	confirmVariant="danger"
	onconfirm={async () => {
		const volId = volumeDeleteTarget;
		volumeDeleteTarget = null;
		if (volId) await handleDelete(volId);
	}}
	oncancel={() => { volumeDeleteTarget = null; }}
/>
