<script lang="ts">
	import { onMount } from 'svelte';
	import type { PhotoDimensions } from '$lib/cards/types';

	let {
		imageUrl,
		personName,
		initialCropData,
		onCropUpdated,
		onClose,
		photoDimensions
	} = $props<{
		imageUrl: string;
		personName: string;
		initialCropData?: { x: number; y: number; width: number; height: number };
		onCropUpdated: (detail: {
			cropData: { x: number; y: number; width: number; height: number };
		}) => void;
		onClose: () => void;
		photoDimensions: PhotoDimensions;
	}>();

	let canvas: HTMLCanvasElement;
	let ctx: CanvasRenderingContext2D;
	let image: HTMLImageElement;
	let isImageLoaded = false;

	// Crop rectangle state
	let crop = {
		x: 0,
		y: 0,
		width: 200,
		height: 200
	};

	// Interaction state
	let isDragging = false;
	let dragStart = { x: 0, y: 0 };

	// Canvas dimensions
	let canvasWidth = 600;
	let canvasHeight = 400;

	// Use the photo card aspect ratio from the selected card's dimensions
	const cropRatio = photoDimensions.width / photoDimensions.height;

	onMount(() => {
		ctx = canvas.getContext('2d')!;
		loadImage();
	});

	async function loadImage() {
		image = new Image();
		image.onload = () => {
			isImageLoaded = true;

			// Calculate canvas size to fit image while maintaining aspect ratio
			const maxWidth = 600;
			const maxHeight = 400;
			const imageAspect = image.width / image.height;

			if (imageAspect > maxWidth / maxHeight) {
				canvasWidth = maxWidth;
				canvasHeight = maxWidth / imageAspect;
			} else {
				canvasHeight = maxHeight;
				canvasWidth = maxHeight * imageAspect;
			}

			canvas.width = canvasWidth;
			canvas.height = canvasHeight;

			// Initialize crop rectangle
			if (initialCropData) {
				// Scale initial crop to canvas dimensions
				const scaleX = canvasWidth / image.width;
				const scaleY = canvasHeight / image.height;
				crop = {
					x: initialCropData.x * scaleX,
					y: initialCropData.y * scaleY,
					width: initialCropData.width * scaleX,
					height: initialCropData.height * scaleY
				};
			} else {
				// Default crop: centered with correct aspect ratio
				const maxSize = Math.min(canvasWidth, canvasHeight) * 0.6;
				const cropWidth = maxSize;
				const cropHeight = cropWidth / cropRatio;

				// If height exceeds canvas, scale down proportionally
				if (cropHeight > canvasHeight * 0.8) {
					const scale = (canvasHeight * 0.8) / cropHeight;
					crop = {
						x: (canvasWidth - (cropWidth * scale)) / 2,
						y: (canvasHeight - (cropHeight * scale)) / 2,
						width: cropWidth * scale,
						height: cropHeight * scale
					};
				} else {
					crop = {
						x: (canvasWidth - cropWidth) / 2,
						y: (canvasHeight - cropHeight) / 2,
						width: cropWidth,
						height: cropHeight
					};
				}
			}

			drawCanvas();
		};
		image.src = imageUrl;
	}

	function drawCanvas() {
		if (!ctx || !isImageLoaded) return;

		// Clear canvas
		ctx.clearRect(0, 0, canvasWidth, canvasHeight);

		// Draw image
		ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);

		// Draw overlay (darken non-crop area)
		ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
		ctx.fillRect(0, 0, canvasWidth, canvasHeight);

		// Clear crop area
		ctx.globalCompositeOperation = 'destination-out';
		ctx.fillRect(crop.x, crop.y, crop.width, crop.height);
		ctx.globalCompositeOperation = 'source-over';

		// Draw crop rectangle border
		ctx.strokeStyle = '#3b82f6';
		ctx.lineWidth = 2;
		ctx.strokeRect(crop.x, crop.y, crop.width, crop.height);
	}

	function getMousePos(e: MouseEvent) {
		const rect = canvas.getBoundingClientRect();
		return {
			x: e.clientX - rect.left,
			y: e.clientY - rect.top
		};
	}

	function isInCropArea(x: number, y: number) {
		return x >= crop.x && x <= crop.x + crop.width && y >= crop.y && y <= crop.y + crop.height;
	}

	function handleMouseDown(e: MouseEvent) {
		const pos = getMousePos(e);
		if (isInCropArea(pos.x, pos.y)) {
			isDragging = true;
			dragStart = { x: pos.x - crop.x, y: pos.y - crop.y };
		}
	}

	function handleMouseMove(e: MouseEvent) {
		const pos = getMousePos(e);

		if (isDragging) {
			crop.x = Math.max(0, Math.min(canvasWidth - crop.width, pos.x - dragStart.x));
			crop.y = Math.max(0, Math.min(canvasHeight - crop.height, pos.y - dragStart.y));
			drawCanvas();
		} else {
			// Update cursor based on hover state
			if (isInCropArea(pos.x, pos.y)) {
				canvas.style.cursor = 'move';
			} else {
				canvas.style.cursor = 'default';
			}
		}
	}

	function handleMouseUp() {
		isDragging = false;
		canvas.style.cursor = 'default';
	}

	function zoom(factor: number) {
		const center = {
			x: crop.x + crop.width / 2,
			y: crop.y + crop.height / 2
		};

		let newWidth = crop.width * factor;
		let newHeight = newWidth / cropRatio;

		// Clamp to min/max size
		newWidth = Math.max(20, Math.min(canvasWidth, newWidth));
		newHeight = newWidth / cropRatio;

		if (newHeight > canvasHeight) {
			newHeight = canvasHeight;
			newWidth = newHeight * cropRatio;
		}

		crop.width = newWidth;
		crop.height = newHeight;
		crop.x = center.x - newWidth / 2;
		crop.y = center.y - newHeight / 2;

		// Ensure it stays within bounds after zooming
		crop.x = Math.max(0, Math.min(canvasWidth - crop.width, crop.x));
		crop.y = Math.max(0, Math.min(canvasHeight - crop.height, crop.y));

		drawCanvas();
	}

	function handleSave() {
		// Scale crop rectangle back to original image dimensions
		const scaleX = image.width / canvasWidth;
		const scaleY = image.height / canvasHeight;

		const finalCrop = {
			x: Math.round(crop.x * scaleX),
			y: Math.round(crop.y * scaleY),
			width: Math.round(crop.width * scaleX),
			height: Math.round(crop.height * scaleY)
		};

		onCropUpdated({ cropData: finalCrop });
		onClose();
	}

	function handleCancel() {
		onClose();
	}

	function handleOverlayClick(event: MouseEvent) {
		if (event.target === event.currentTarget) {
			onClose();
		}
	}

	function handleKeyDown(event: KeyboardEvent) {
		if (event.key === 'Escape') {
			onClose();
		}
	}
</script>

<div
	class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
	onclick={handleOverlayClick}
	onkeydown={handleKeyDown}
	role="dialog"
	aria-modal="true"
	aria-labelledby="dialog-title"
	tabindex="-1"
>
	<div class="bg-white rounded-lg shadow-xl max-w-4xl w-full mx-4" role="document">
		<div class="p-6">
			<div class="flex items-center justify-between mb-4">
				<h3 id="dialog-title" class="text-lg font-semibold text-gray-800">
					Crop Photo: {personName}
				</h3>
				<button onclick={onClose} class="text-gray-400 hover:text-gray-600" aria-label="Close">
					<svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
						<path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="2"
							d="M6 18L18 6M6 6l12 12"
						/>
					</svg>
				</button>
			</div>

			<div class="relative mb-4 p-2 rounded-md text-center">
				<canvas
					bind:this={canvas}
					onmousedown={handleMouseDown}
					onmousemove={handleMouseMove}
					onmouseup={handleMouseUp}
					onmouseleave={handleMouseUp}
					class="mx-auto"
					style="max-width: 100%; height: auto;"
				></canvas>
				<div class="absolute bottom-4 right-4 flex space-x-2">
					<button
						onclick={() => zoom(1 / 1.1)}
						class="flex h-10 w-10 items-center justify-center rounded-full bg-gray-700 bg-opacity-50 text-white hover:bg-opacity-75"
						aria-label="Zoom out"
					>
						<svg
							xmlns="http://www.w3.org/2000/svg"
							viewBox="0 0 20 20"
							fill="currentColor"
							class="h-6 w-6"
						>
							<path
								fill-rule="evenodd"
								d="M4 10a.75.75 0 01.75-.75h10.5a.75.75 0 010 1.5H4.75A.75.75 0 014 10z"
								clip-rule="evenodd"
							/>
						</svg>
					</button>
					<button
						onclick={() => zoom(1.1)}
						class="flex h-10 w-10 items-center justify-center rounded-full bg-gray-700 bg-opacity-50 text-white hover:bg-opacity-75"
						aria-label="Zoom in"
					>
						<svg
							xmlns="http://www.w3.org/2000/svg"
							viewBox="0 0 20 20"
							fill="currentColor"
							class="h-6 w-6"
						>
							<path
								d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
							/>
						</svg>
					</button>
				</div>
			</div>

			<div class="flex justify-end space-x-3">
				<button
					onclick={handleCancel}
					class="px-4 py-2 bg-gray-200 text-gray-700 rounded-lg font-medium hover:bg-gray-300"
				>
					Cancel
				</button>
				<button
					onclick={handleSave}
					class="px-4 py-2 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700"
				>
					Save Crop
				</button>
			</div>
		</div>
	</div>
</div>
