<script lang="ts">
	interface Props {
		id: number;
		frontImage: string;
		backImage: string;
		flipped?: boolean;
		x?: number;
		y?: number;
		zIndex?: number;
		canvasOffset?: { x: number; y: number };
		canvasZoom?: number;
		onMove?: (id: number, x: number, y: number) => void;
		onClick?: (id: number) => void;
		onDrop?: (id: number, x: number, y: number) => void;
	}

	let {
		id,
		frontImage,
		backImage,
		flipped = $bindable(false),
		x = $bindable(0),
		y = $bindable(0),
		zIndex = $bindable(0),
		canvasOffset = { x: 0, y: 0 },
		canvasZoom = 1,
		onMove,
		onClick,
		onDrop
	}: Props = $props();

	let isDragging = $state(false);
	let dragOffset = $state({ x: 0, y: 0 });
	let dragStartPos = $state({ x: 0, y: 0 });
	let hasMoved = $state(false);
	let cardElement: HTMLDivElement;

	function handleMouseDown(event: MouseEvent) {
		if (event.button !== 0) return;
		
		isDragging = true;
		hasMoved = false;
		
		// Calculate offset relative to card position in canvas coordinates
		dragOffset = {
			x: (event.clientX - canvasOffset.x) / canvasZoom - x,
			y: (event.clientY - canvasOffset.y) / canvasZoom - y
		};
		dragStartPos = {
			x: event.clientX,
			y: event.clientY
		};
		
		event.preventDefault();
	}

	function handleMouseMove(event: MouseEvent) {
		if (!isDragging) return;
		
		const deltaX = Math.abs(event.clientX - dragStartPos.x);
		const deltaY = Math.abs(event.clientY - dragStartPos.y);
		
		if (deltaX > 10 || deltaY > 10) {
			hasMoved = true;
		}
		
		const newX = (event.clientX - canvasOffset.x) / canvasZoom - dragOffset.x;
		const newY = (event.clientY - canvasOffset.y) / canvasZoom - dragOffset.y;
		
		x = newX;
		y = newY;
		
		onMove?.(id, newX, newY);
	}

	function handleMouseUp() {
		if (isDragging) {
			onDrop?.(id, x, y);
		}
		isDragging = false;
	}

	function handleClick(event: MouseEvent) {
		if (!hasMoved) {
			flipped = !flipped;
			onClick?.(id);
		}
	}

	function handleTouchStart(event: TouchEvent) {
		if (event.touches.length !== 1) return;
		event.stopPropagation(); // Prevent canvas panning
		
		const touch = event.touches[0];
		isDragging = true;
		hasMoved = false;
		
		// Calculate offset relative to card position in canvas coordinates
		dragOffset = {
			x: (touch.clientX - canvasOffset.x) / canvasZoom - x,
			y: (touch.clientY - canvasOffset.y) / canvasZoom - y
		};
		dragStartPos = {
			x: touch.clientX,
			y: touch.clientY
		};
		
		event.preventDefault();
	}

	function handleTouchMove(event: TouchEvent) {
		if (!isDragging || event.touches.length !== 1) return;
		
		const touch = event.touches[0];
		const deltaX = Math.abs(touch.clientX - dragStartPos.x);
		const deltaY = Math.abs(touch.clientY - dragStartPos.y);
		
		if (deltaX > 10 || deltaY > 10) {
			hasMoved = true;
		}
		
		const newX = (touch.clientX - canvasOffset.x) / canvasZoom - dragOffset.x;
		const newY = (touch.clientY - canvasOffset.y) / canvasZoom - dragOffset.y;
		
		x = newX;
		y = newY;
		
		onMove?.(id, newX, newY);
		event.preventDefault();
	}

	function handleTouchEnd(event: TouchEvent) {
		if (isDragging) {
			onDrop?.(id, x, y);
			if (!hasMoved) {
				flipped = !flipped;
				onClick?.(id);
			}
		}
		isDragging = false;
		event.preventDefault();
	}

	$effect(() => {
		if (isDragging) {
			document.addEventListener('mousemove', handleMouseMove);
			document.addEventListener('mouseup', handleMouseUp);
			return () => {
				document.removeEventListener('mousemove', handleMouseMove);
				document.removeEventListener('mouseup', handleMouseUp);
			};
		}
	});
</script>

<div
	bind:this={cardElement}
	class="card"
	class:flipped
	class:dragging={isDragging}
	style="left: {x}px; top: {y}px; z-index: {zIndex};"
	onmousedown={handleMouseDown}
	onclick={handleClick}
	ontouchstart={handleTouchStart}
	ontouchmove={handleTouchMove}
	ontouchend={handleTouchEnd}
	role="button"
	tabindex="0"
>
	<div class="card-inner">
		<div class="card-front">
			<img src={frontImage} alt="Card front" />
		</div>
		<div class="card-back">
			<img src={backImage} alt="Card back" />
		</div>
	</div>
</div>

<style>
	.card {
		position: absolute;
		width: 220px;
		height: 300px;
		cursor: pointer;
		perspective: 1000px;
		user-select: none;
	}

	.card.dragging {
		cursor: grabbing;
		z-index: 1000 !important;
	}

	.card-inner {
		position: relative;
		width: 100%;
		height: 100%;
		text-align: center;
		transition: transform 0.6s;
		transform-style: preserve-3d;
	}

	.card.flipped .card-inner {
		transform: rotateY(180deg);
	}

	.card-front,
	.card-back {
		position: absolute;
		width: 100%;
		height: 100%;
		backface-visibility: hidden;
		border-radius: 27px;
		overflow: hidden;
		box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
	}

	.card-front {
		background: white;
	}

	.card-back {
		transform: rotateY(180deg);
		background: white;
	}

	.card img {
		width: 100%;
		height: 100%;
		object-fit: cover;
		border-radius: 30px;
	}

	.card:hover {
		transform: translateY(-2px);
		transition: transform 0.2s ease;
	}

	.card.dragging:hover {
		transform: none;
	}
</style>