<script lang="ts">
	import { Loader2 } from 'lucide-svelte';
	import type { ImageEntry, Device, PipelineConfig, CropRegion } from '$lib/types';
	import { processImageWithPipeline } from '$lib/processing/pipeline';
	import CropOverlay from './CropOverlay.svelte';

	interface Props {
		image: ImageEntry;
		device: Device;
		config: PipelineConfig;
		onPreviewUpdate: (dataUrl: string) => void;
		onProcessingChange: (processing: boolean) => void;
		onConfigChange?: (config: PipelineConfig) => void;
	}

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

	let previewDataUrl = $state<string | null>(null);
	let isProcessing = $state(false);
	let debounceTimer: ReturnType<typeof setTimeout> | null = null;

	const isManualCrop = $derived(config.crop.enabled && config.crop.mode === 'manual');
	const targetAspect = $derived(device.width / device.height);

	// Track config changes and trigger debounced processing
	$effect(() => {
		// Access config to create dependency (but skip processing in manual crop mode without region)
		const configStr = JSON.stringify(config);

		// Don't process if in manual crop mode - wait for region to be set
		if (isManualCrop && !config.crop.region) {
			return;
		}

		// Clear existing timer
		if (debounceTimer) {
			clearTimeout(debounceTimer);
		}

		// Debounce processing
		debounceTimer = setTimeout(() => {
			processPreview();
		}, 150);

		return () => {
			if (debounceTimer) {
				clearTimeout(debounceTimer);
			}
		};
	});

	async function processPreview(): Promise<void> {
		if (!image.file) return;

		isProcessing = true;
		onProcessingChange(true);

		try {
			const { dataUrl } = await processImageWithPipeline(image.file, device, config);
			previewDataUrl = dataUrl;
			onPreviewUpdate(dataUrl);
		} catch (err) {
			console.error('Preview processing failed:', err);
		} finally {
			isProcessing = false;
			onProcessingChange(false);
		}
	}

	// Initialize with current processed image
	$effect(() => {
		if (image.processedDataUrl && !previewDataUrl) {
			previewDataUrl = image.processedDataUrl;
		}
	});

	function handleCropRegionChange(region: CropRegion): void {
		if (onConfigChange) {
			onConfigChange({
				...config,
				crop: { ...config.crop, region }
			});
		}
	}
</script>

<div class="flex flex-col items-center gap-4">
	<!-- Preview container -->
	<div class="relative w-full max-w-md aspect-[3/4] bg-grey-100 rounded-lg overflow-hidden shadow-inner">
		{#if isManualCrop && image.originalDataUrl && image.originalDimensions}
			<!-- Show original image with crop overlay in manual mode -->
			<img
				src={image.originalDataUrl}
				alt="Original"
				class="absolute inset-0 w-full h-full object-contain"
			/>
			<CropOverlay
				imageWidth={image.originalDimensions.width}
				imageHeight={image.originalDimensions.height}
				{targetAspect}
				region={config.crop.region}
				onRegionChange={handleCropRegionChange}
			/>
		{:else if previewDataUrl}
			<img
				src={previewDataUrl}
				alt="Preview"
				class="absolute inset-0 w-full h-full object-contain"
			/>
		{:else if image.originalDataUrl}
			<img
				src={image.originalDataUrl}
				alt="Original"
				class="absolute inset-0 w-full h-full object-contain opacity-50"
			/>
		{/if}

		<!-- Processing overlay -->
		{#if isProcessing}
			<div class="absolute inset-0 flex items-center justify-center bg-white/70">
				<div class="flex flex-col items-center gap-2">
					<Loader2 class="w-8 h-8 text-accent animate-spin" />
					<span class="text-sm text-grey-500">Processing...</span>
				</div>
			</div>
		{/if}
	</div>

	<!-- Image info -->
	<div class="text-center">
		<p class="text-sm font-medium text-ink">{image.filename}</p>
		{#if image.originalDimensions}
			<p class="text-xs text-grey-400 font-mono mt-1">
				{image.originalDimensions.width} × {image.originalDimensions.height}
				→
				{device.width} × {device.height}
			</p>
		{/if}
		{#if isManualCrop}
			<p class="text-xs text-accent mt-1">Drag to position, drag corners to resize</p>
		{/if}
	</div>
</div>
