<script lang="ts">
import type { Annotation } from '$lib/types';

type DrawRect = {
	x: number;
	y: number;
	width: number;
	height: number;
};

let {
	annotations = [],
	canDraw,
	color,
	blockNumbers = {},
	activeAnnotationId = null,
	onDraw,
	onAnnotationClick
}: {
	annotations: Annotation[];
	canDraw: boolean;
	color: string;
	blockNumbers?: Record<string, number>;
	activeAnnotationId?: string | null;
	onDraw: (rect: DrawRect) => void;
	onAnnotationClick?: (id: string) => void;
} = $props();

let drawStart = $state<{ x: number; y: number } | null>(null);
let drawRect = $state<DrawRect | null>(null);

function hexToRgba(hex: string, alpha: number): string {
	const r = parseInt(hex.slice(1, 3), 16);
	const g = parseInt(hex.slice(3, 5), 16);
	const b = parseInt(hex.slice(5, 7), 16);
	return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}

function getNormalizedCoords(event: PointerEvent, element: HTMLElement): { x: number; y: number } {
	const rect = element.getBoundingClientRect();
	return {
		x: (event.clientX - rect.left) / rect.width,
		y: (event.clientY - rect.top) / rect.height
	};
}

function handlePointerDown(event: PointerEvent) {
	if (!canDraw) return;

	if ((event.target as HTMLElement).closest('[data-annotation]')) return;

	const container = event.currentTarget as HTMLElement;
	container.setPointerCapture(event.pointerId);

	const coords = getNormalizedCoords(event, container);
	drawStart = coords;
	drawRect = { x: coords.x, y: coords.y, width: 0, height: 0 };
}

function handlePointerMove(event: PointerEvent) {
	if (!canDraw || !drawStart) return;

	const container = event.currentTarget as HTMLElement;
	const coords = getNormalizedCoords(event, container);

	const x = Math.min(drawStart.x, coords.x);
	const y = Math.min(drawStart.y, coords.y);
	const width = Math.abs(coords.x - drawStart.x);
	const height = Math.abs(coords.y - drawStart.y);

	drawRect = { x, y, width, height };
}

function handlePointerUp(event: PointerEvent) {
	if (!canDraw || !drawStart || !drawRect) return;

	const container = event.currentTarget as HTMLElement;
	const coords = getNormalizedCoords(event, container);

	const x = Math.min(drawStart.x, coords.x);
	const y = Math.min(drawStart.y, coords.y);
	const width = Math.abs(coords.x - drawStart.x);
	const height = Math.abs(coords.y - drawStart.y);

	if (width > 0.01 && height > 0.01) {
		onDraw({ x, y, width, height });
	}

	drawStart = null;
	drawRect = null;
}

let hoveredId = $state<string | null>(null);

const containerStyle = $derived(
	`position: absolute; top: 0; left: 0; width: 100%; height: 100%;${canDraw ? ' cursor: crosshair; touch-action: none;' : ''}`
);
</script>

<div
	style={containerStyle}
	role="presentation"
	onpointerdown={handlePointerDown}
	onpointermove={handlePointerMove}
	onpointerup={handlePointerUp}
>
	{#each annotations as annotation (annotation.id)}
		<div
			data-testid="annotation-{annotation.id}"
			data-annotation
			role="button"
			tabindex="0"
			aria-label="Block anzeigen"
			onclick={() => onAnnotationClick?.(annotation.id)}
			onkeydown={(e) => {
				if (e.key === 'Enter' || e.key === ' ') onAnnotationClick?.(annotation.id);
			}}
			onpointerenter={() => (hoveredId = annotation.id)}
			onpointerleave={() => (hoveredId = null)}
			style="
				position: absolute;
				left: {annotation.x * 100}%;
				top: {annotation.y * 100}%;
				width: {annotation.width * 100}%;
				height: {annotation.height * 100}%;
				background-color: {hexToRgba(annotation.color, hoveredId === annotation.id || annotation.id === activeAnnotationId ? 0.5 : 0.3)};
				box-shadow: {annotation.id === activeAnnotationId ? `inset 0 0 0 2px ${hexToRgba(annotation.color, 0.8)}` : hoveredId === annotation.id ? `inset 0 0 0 2px ${hexToRgba(annotation.color, 0.8)}` : 'none'};
				opacity: {activeAnnotationId && annotation.id !== activeAnnotationId ? 0.3 : 1};
				pointer-events: auto;
				cursor: pointer;
				transition: background-color 0.15s ease, box-shadow 0.15s ease, opacity 0.3s ease;
			"
		>
			{#if blockNumbers[annotation.id]}
				<div
					style="
						position: absolute;
						top: -8px;
						left: -8px;
						width: 20px;
						height: 20px;
						border-radius: 50%;
						background-color: {annotation.color};
						color: white;
						font-size: 11px;
						font-family: sans-serif;
						font-weight: 700;
						display: flex;
						align-items: center;
						justify-content: center;
						pointer-events: none;
						box-shadow: 0 1px 3px rgba(0,0,0,0.3);
					"
				>
					{blockNumbers[annotation.id]}
				</div>
			{/if}
		</div>
	{/each}

	{#if drawRect && drawRect.width > 0}
		<div
			style="
				position: absolute;
				left: {drawRect.x * 100}%;
				top: {drawRect.y * 100}%;
				width: {drawRect.width * 100}%;
				height: {drawRect.height * 100}%;
				border: 2px dashed {color};
				opacity: 0.3;
				pointer-events: none;
			"
		></div>
	{/if}
</div>
