<script lang="ts">
	import { uploadMedia } from '$lib/api';

	interface Props {
		accessToken?: string;
		onrecorded?: (result: { media_node_id: string; cas_hash: string }) => void;
		onerror?: (message: string) => void;
		sourceId?: string;
		disabled?: boolean;
	}

	let { accessToken, onrecorded, onerror, sourceId, disabled = false }: Props = $props();

	type DrawState = 'idle' | 'drawing' | 'uploading';

	let drawState: DrawState = $state('idle');
	let canvasEl: HTMLCanvasElement | undefined = $state();
	let ctx: CanvasRenderingContext2D | null = $state(null);
	let isPointerDown = $state(false);
	let hasStrokes = $state(false);
	let brushColor = $state('#000000');
	let brushSize = $state(3);

	// Stroke history for undo
	let strokes: ImageData[] = [];

	function openCanvas() {
		drawState = 'drawing';
		hasStrokes = false;
		strokes = [];
		// Wait for DOM to render the canvas
		requestAnimationFrame(() => {
			if (!canvasEl) return;
			setupCanvas();
		});
	}

	function setupCanvas() {
		if (!canvasEl) return;
		const container = canvasEl.parentElement;
		if (!container) return;

		// Size canvas to container
		const rect = container.getBoundingClientRect();
		const dpr = window.devicePixelRatio || 1;
		const w = Math.floor(rect.width);
		const h = Math.min(Math.floor(rect.width * 0.6), 400);

		canvasEl.width = w * dpr;
		canvasEl.height = h * dpr;
		canvasEl.style.width = w + 'px';
		canvasEl.style.height = h + 'px';

		ctx = canvasEl.getContext('2d');
		if (!ctx) return;
		ctx.scale(dpr, dpr);

		// White background
		ctx.fillStyle = '#ffffff';
		ctx.fillRect(0, 0, w, h);

		ctx.lineCap = 'round';
		ctx.lineJoin = 'round';
	}

	function getPos(e: PointerEvent): { x: number; y: number } {
		if (!canvasEl) return { x: 0, y: 0 };
		const rect = canvasEl.getBoundingClientRect();
		return {
			x: e.clientX - rect.left,
			y: e.clientY - rect.top,
		};
	}

	function onPointerDown(e: PointerEvent) {
		if (!ctx || !canvasEl) return;
		e.preventDefault();
		canvasEl.setPointerCapture(e.pointerId);
		isPointerDown = true;

		// Save state for undo
		strokes.push(ctx.getImageData(0, 0, canvasEl.width, canvasEl.height));

		const pos = getPos(e);
		ctx.strokeStyle = brushColor;
		ctx.lineWidth = brushSize;
		ctx.beginPath();
		ctx.moveTo(pos.x, pos.y);
	}

	function onPointerMove(e: PointerEvent) {
		if (!isPointerDown || !ctx) return;
		e.preventDefault();
		const pos = getPos(e);
		ctx.lineTo(pos.x, pos.y);
		ctx.stroke();
	}

	function onPointerUp(e: PointerEvent) {
		if (!isPointerDown) return;
		e.preventDefault();
		isPointerDown = false;
		hasStrokes = true;
	}

	function undo() {
		if (!ctx || !canvasEl || strokes.length === 0) return;
		const prev = strokes.pop()!;
		ctx.putImageData(prev, 0, 0);
		if (strokes.length === 0) hasStrokes = false;
	}

	function clearCanvas() {
		if (!ctx || !canvasEl) return;
		const dpr = window.devicePixelRatio || 1;
		const w = canvasEl.width / dpr;
		const h = canvasEl.height / dpr;
		ctx.fillStyle = '#ffffff';
		ctx.fillRect(0, 0, w, h);
		strokes = [];
		hasStrokes = false;
	}

	function cancel() {
		drawState = 'idle';
		strokes = [];
	}

	async function exportAndUpload() {
		if (!canvasEl || !accessToken) return;

		drawState = 'uploading';

		try {
			const blob = await new Promise<Blob | null>((resolve) => {
				canvasEl!.toBlob(resolve, 'image/png');
			});

			if (!blob) {
				onerror?.('Kunne ikke eksportere tegning');
				drawState = 'drawing';
				return;
			}

			const timestamp = new Date().toISOString().slice(0, 19).replace(/[T:]/g, '-');
			const file = new File([blob], `skisse-${timestamp}.png`, { type: 'image/png' });

			const result = await uploadMedia(accessToken, {
				file,
				title: 'Skisse',
				visibility: 'hidden',
				source_id: sourceId,
				metadata_extra: { source: 'drawing' },
			});

			onrecorded?.({
				media_node_id: result.media_node_id,
				cas_hash: result.cas_hash,
			});

			drawState = 'idle';
			strokes = [];
		} catch (e) {
			onerror?.(e instanceof Error ? e.message : 'Feil ved opplasting av tegning');
			drawState = 'drawing';
		}
	}

	const colors = ['#000000', '#ef4444', '#3b82f6', '#22c55e', '#f59e0b', '#8b5cf6'];
</script>

{#if drawState === 'idle'}
	<button
		onclick={openCanvas}
		disabled={disabled || !accessToken}
		class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full text-gray-400 transition-colors hover:bg-amber-50 hover:text-amber-600 disabled:cursor-not-allowed disabled:opacity-40"
		aria-label="Tegn en skisse"
		title="Tegn en skisse"
	>
		<!-- Pencil icon -->
		<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
			<path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
		</svg>
	</button>
{:else if drawState === 'uploading'}
	<div class="flex items-center gap-1.5">
		<svg class="h-4 w-4 animate-spin text-amber-600" fill="none" viewBox="0 0 24 24">
			<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
			<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
		</svg>
		<span class="text-xs text-amber-600">Laster opp skisse…</span>
	</div>
{/if}

{#if drawState === 'drawing'}
	<!-- Fullscreen overlay for drawing -->
	<div class="fixed inset-0 z-50 flex flex-col bg-white">
		<!-- Toolbar -->
		<div class="flex items-center justify-between border-b border-gray-200 px-3 py-2">
			<div class="flex items-center gap-2">
				<button
					onclick={cancel}
					class="rounded-lg px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100"
				>
					Avbryt
				</button>
			</div>

			<span class="text-sm font-medium text-gray-700">Skisse</span>

			<div class="flex items-center gap-2">
				<button
					onclick={undo}
					disabled={!hasStrokes}
					class="rounded-lg px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100 disabled:opacity-30"
					title="Angre"
				>
					<!-- Undo icon -->
					<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
						<path stroke-linecap="round" stroke-linejoin="round" d="M3 10h10a5 5 0 015 5v2M3 10l4-4M3 10l4 4" />
					</svg>
				</button>
				<button
					onclick={clearCanvas}
					disabled={!hasStrokes}
					class="rounded-lg px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100 disabled:opacity-30"
					title="Tøm"
				>
					Tøm
				</button>
				<button
					onclick={exportAndUpload}
					disabled={!hasStrokes}
					class="rounded-lg bg-blue-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-40"
				>
					Send
				</button>
			</div>
		</div>

		<!-- Color & size picker -->
		<div class="flex items-center gap-3 border-b border-gray-100 px-3 py-2">
			<div class="flex items-center gap-1">
				{#each colors as color}
					<button
						onclick={() => { brushColor = color; }}
						class="h-6 w-6 rounded-full border-2 transition-transform"
						class:scale-110={brushColor === color}
						class:border-gray-400={brushColor === color}
						class:border-transparent={brushColor !== color}
						style="background-color: {color}"
						aria-label="Farge {color}"
					></button>
				{/each}
			</div>
			<div class="flex items-center gap-2">
				<span class="text-xs text-gray-400">Tykkelse</span>
				<input
					type="range"
					min="1"
					max="20"
					bind:value={brushSize}
					class="h-1 w-20 accent-gray-600"
				/>
				<span class="w-5 text-right text-xs text-gray-500">{brushSize}</span>
			</div>
		</div>

		<!-- Canvas area -->
		<div class="flex flex-1 items-center justify-center bg-gray-50 p-4">
			<div class="w-full max-w-2xl rounded-lg border border-gray-200 bg-white shadow-sm">
				<canvas
					bind:this={canvasEl}
					onpointerdown={onPointerDown}
					onpointermove={onPointerMove}
					onpointerup={onPointerUp}
					onpointerleave={onPointerUp}
					class="touch-none cursor-crosshair rounded-lg"
					style="display: block; width: 100%;"
				></canvas>
			</div>
		</div>
	</div>
{/if}
