<script lang="ts">
	import { Save } from 'lucide-svelte';
	import type { PipelineConfig, Device, CropMode, ResizeMode, GreyscaleMethod, DitherAlgorithm } from '$lib/types';
	import { pipelineStore } from '$lib/stores/pipeline.svelte';
	import PipelineStep from './PipelineStep.svelte';

	interface Props {
		config: PipelineConfig;
		device: Device;
		onConfigChange: (config: PipelineConfig) => void;
	}

	let { config, device, onConfigChange }: Props = $props();

	// Preset management
	let showSaveDialog = $state(false);
	let newPresetName = $state('');

	// Helper to update a step
	function updateStep<K extends keyof PipelineConfig>(
		step: K,
		updates: Partial<PipelineConfig[K]>
	): void {
		onConfigChange({
			...config,
			[step]: { ...config[step], ...updates }
		});
	}

	function handlePresetChange(e: Event): void {
		const select = e.target as HTMLSelectElement;
		const preset = pipelineStore.allPresets.find((p) => p.id === select.value);
		if (preset) {
			onConfigChange(JSON.parse(JSON.stringify(preset.config)));
		}
	}

	function handleSavePreset(): void {
		if (!newPresetName.trim()) return;
		pipelineStore.saveAsPreset(newPresetName.trim());
		showSaveDialog = false;
		newPresetName = '';
	}

	// Options for selects
	const cropModes: { value: CropMode; label: string }[] = [
		{ value: 'center', label: 'Center' },
		{ value: 'top', label: 'Top' },
		{ value: 'bottom', label: 'Bottom' },
		{ value: 'manual', label: 'Manual' }
	];

	const resizeModes: { value: ResizeMode; label: string }[] = [
		{ value: 'cover', label: 'Cover (fill, may crop)' },
		{ value: 'contain', label: 'Contain (fit, may pad)' },
		{ value: 'stretch', label: 'Stretch (distort)' }
	];

	const greyscaleMethods: { value: GreyscaleMethod; label: string }[] = [
		{ value: 'luminosity', label: 'Luminosity (natural)' },
		{ value: 'average', label: 'Average' },
		{ value: 'lightness', label: 'Lightness' },
		{ value: 'red', label: 'Red channel' },
		{ value: 'green', label: 'Green channel' },
		{ value: 'blue', label: 'Blue channel' }
	];

	const ditherAlgorithms: { value: DitherAlgorithm; label: string }[] = [
		{ value: 'floyd-steinberg', label: 'Floyd-Steinberg' },
		{ value: 'ordered', label: 'Ordered (Bayer)' },
		{ value: 'atkinson', label: 'Atkinson' }
	];
</script>

<div class="flex flex-col h-full">
	<!-- Preset selector -->
	<div class="p-4 border-b border-grey-200">
		<label class="block text-xs font-medium text-grey-500 uppercase tracking-wide mb-2">
			Preset
		</label>
		<div class="flex gap-2">
			<select
				class="
					flex-1 px-3 py-2
					bg-white text-ink text-sm
					border border-grey-200 rounded-md
					focus:outline-none focus:ring-2 focus:ring-accent focus:border-accent
				"
				value={pipelineStore.selectedPresetId ?? ''}
				onchange={handlePresetChange}
			>
				{#each pipelineStore.allPresets as preset}
					<option value={preset.id}>
						{preset.name}{preset.isBuiltIn ? '' : ' (custom)'}
					</option>
				{/each}
			</select>

			<button
				type="button"
				class="
					p-2
					bg-white text-grey-500
					border border-grey-200 rounded-md
					hover:bg-grey-50 hover:text-ink
					transition-colors duration-150
				"
				onclick={() => (showSaveDialog = true)}
				title="Save as preset"
			>
				<Save class="w-4 h-4" />
			</button>
		</div>

		{#if showSaveDialog}
			<div class="mt-2 flex gap-2">
				<input
					type="text"
					bind:value={newPresetName}
					placeholder="Preset name"
					class="
						flex-1 px-3 py-1.5
						bg-white text-ink text-sm
						border border-grey-200 rounded-md
						focus:outline-none focus:ring-2 focus:ring-accent focus:border-accent
					"
				/>
				<button
					type="button"
					class="px-3 py-1.5 bg-accent text-white text-sm rounded-md hover:bg-accent-hover"
					onclick={handleSavePreset}
				>
					Save
				</button>
				<button
					type="button"
					class="px-3 py-1.5 text-grey-500 text-sm hover:text-ink"
					onclick={() => (showSaveDialog = false)}
				>
					Cancel
				</button>
			</div>
		{/if}
	</div>

	<!-- Pipeline steps -->
	<div class="flex-1 overflow-auto">
		<div class="text-xs font-medium text-grey-500 uppercase tracking-wide px-4 py-2 bg-grey-50">
			Pipeline Steps
		</div>

		<!-- Crop -->
		<PipelineStep
			label="Crop"
			enabled={config.crop.enabled}
			onToggle={(enabled) => updateStep('crop', { enabled })}
			defaultExpanded
		>
			{#snippet children()}
				<label class="block text-xs text-grey-500 mb-1">Mode</label>
				<select
					class="w-full px-2 py-1.5 text-sm border border-grey-200 rounded-md"
					value={config.crop.mode}
					onchange={(e) => updateStep('crop', { mode: (e.target as HTMLSelectElement).value as CropMode })}
				>
					{#each cropModes as mode}
						<option value={mode.value}>{mode.label}</option>
					{/each}
				</select>
			{/snippet}
		</PipelineStep>

		<!-- Resize -->
		<PipelineStep
			label="Resize"
			enabled={config.resize.enabled}
			onToggle={(enabled) => updateStep('resize', { enabled })}
			defaultExpanded
		>
			{#snippet children()}
				<label class="block text-xs text-grey-500 mb-1">Mode</label>
				<select
					class="w-full px-2 py-1.5 text-sm border border-grey-200 rounded-md"
					value={config.resize.mode}
					onchange={(e) => updateStep('resize', { mode: (e.target as HTMLSelectElement).value as ResizeMode })}
				>
					{#each resizeModes as mode}
						<option value={mode.value}>{mode.label}</option>
					{/each}
				</select>
			{/snippet}
		</PipelineStep>

		<!-- Brightness -->
		<PipelineStep
			label="Brightness"
			enabled={config.brightness.enabled}
			onToggle={(enabled) => updateStep('brightness', { enabled })}
		>
			{#snippet children()}
				<div class="flex items-center gap-2">
					<input
						type="range"
						min="-100"
						max="100"
						step="1"
						value={config.brightness.value}
						oninput={(e) => updateStep('brightness', { value: parseInt((e.target as HTMLInputElement).value) })}
						class="flex-1"
					/>
					<span class="text-xs text-grey-500 w-8 text-right">{config.brightness.value}</span>
				</div>
			{/snippet}
		</PipelineStep>

		<!-- Contrast -->
		<PipelineStep
			label="Contrast"
			enabled={config.contrast.enabled}
			onToggle={(enabled) => updateStep('contrast', { enabled })}
		>
			{#snippet children()}
				<div class="flex items-center gap-2">
					<input
						type="range"
						min="-100"
						max="100"
						step="1"
						value={config.contrast.value}
						oninput={(e) => updateStep('contrast', { value: parseInt((e.target as HTMLInputElement).value) })}
						class="flex-1"
					/>
					<span class="text-xs text-grey-500 w-8 text-right">{config.contrast.value}</span>
				</div>
			{/snippet}
		</PipelineStep>

		<!-- Gamma -->
		<PipelineStep
			label="Gamma"
			enabled={config.gamma.enabled}
			onToggle={(enabled) => updateStep('gamma', { enabled })}
		>
			{#snippet children()}
				<div class="flex items-center gap-2">
					<input
						type="range"
						min="0.2"
						max="3"
						step="0.1"
						value={config.gamma.value}
						oninput={(e) => updateStep('gamma', { value: parseFloat((e.target as HTMLInputElement).value) })}
						class="flex-1"
					/>
					<span class="text-xs text-grey-500 w-10 text-right">{config.gamma.value.toFixed(1)}</span>
				</div>
			{/snippet}
		</PipelineStep>

		<!-- Auto-levels -->
		<PipelineStep
			label="Auto-levels"
			enabled={config.autoLevels.enabled}
			onToggle={(enabled) => updateStep('autoLevels', { enabled })}
		>
			{#snippet children()}
				<label class="block text-xs text-grey-500 mb-1">Clip %</label>
				<div class="flex items-center gap-2">
					<input
						type="range"
						min="0"
						max="5"
						step="0.1"
						value={config.autoLevels.clipPercent}
						oninput={(e) => updateStep('autoLevels', { clipPercent: parseFloat((e.target as HTMLInputElement).value) })}
						class="flex-1"
					/>
					<span class="text-xs text-grey-500 w-10 text-right">{config.autoLevels.clipPercent.toFixed(1)}%</span>
				</div>
			{/snippet}
		</PipelineStep>

		<!-- Greyscale -->
		<PipelineStep
			label="Greyscale"
			enabled={config.greyscale.enabled}
			onToggle={(enabled) => updateStep('greyscale', { enabled })}
			defaultExpanded
		>
			{#snippet children()}
				<label class="block text-xs text-grey-500 mb-1">Method</label>
				<select
					class="w-full px-2 py-1.5 text-sm border border-grey-200 rounded-md"
					value={config.greyscale.method}
					onchange={(e) => updateStep('greyscale', { method: (e.target as HTMLSelectElement).value as GreyscaleMethod })}
				>
					{#each greyscaleMethods as method}
						<option value={method.value}>{method.label}</option>
					{/each}
				</select>
			{/snippet}
		</PipelineStep>

		<!-- Sharpen -->
		<PipelineStep
			label="Sharpen"
			enabled={config.sharpen.enabled}
			onToggle={(enabled) => updateStep('sharpen', { enabled })}
		>
			{#snippet children()}
				<label class="block text-xs text-grey-500 mb-1">Amount</label>
				<div class="flex items-center gap-2">
					<input
						type="range"
						min="0"
						max="100"
						step="1"
						value={config.sharpen.amount}
						oninput={(e) => updateStep('sharpen', { amount: parseInt((e.target as HTMLInputElement).value) })}
						class="flex-1"
					/>
					<span class="text-xs text-grey-500 w-8 text-right">{config.sharpen.amount}</span>
				</div>
			{/snippet}
		</PipelineStep>

		<!-- Quantize -->
		<PipelineStep
			label="Quantize"
			enabled={config.quantize.enabled}
			onToggle={(enabled) => updateStep('quantize', { enabled })}
		>
			{#snippet children()}
				<label class="block text-xs text-grey-500 mb-1">Levels</label>
				<select
					class="w-full px-2 py-1.5 text-sm border border-grey-200 rounded-md"
					value={config.quantize.levels}
					onchange={(e) => updateStep('quantize', { levels: parseInt((e.target as HTMLSelectElement).value) })}
				>
					<option value={device.greyLevels}>{device.greyLevels} (device default)</option>
					<option value="2">2</option>
					<option value="4">4</option>
					<option value="8">8</option>
					<option value="16">16</option>
					<option value="32">32</option>
					<option value="64">64</option>
					<option value="256">256 (no quantization)</option>
				</select>
			{/snippet}
		</PipelineStep>

		<!-- Dither -->
		<PipelineStep
			label="Dither"
			enabled={config.dither.enabled}
			onToggle={(enabled) => updateStep('dither', { enabled })}
		>
			{#snippet children()}
				<label class="block text-xs text-grey-500 mb-1">Algorithm</label>
				<select
					class="w-full px-2 py-1.5 text-sm border border-grey-200 rounded-md"
					value={config.dither.algorithm}
					onchange={(e) => updateStep('dither', { algorithm: (e.target as HTMLSelectElement).value as DitherAlgorithm })}
				>
					{#each ditherAlgorithms as algo}
						<option value={algo.value}>{algo.label}</option>
					{/each}
				</select>
			{/snippet}
		</PipelineStep>
	</div>
</div>
