<script lang="ts">
import type { Annotation } from '$lib/shared/types';
import { m } from '$lib/paraglide/messages.js';
import AnnotationEditOverlay from './AnnotationEditOverlay.svelte';

let {
	annotation,
	isHovered,
	isActive,
	faded = false,
	dimmed = false,
	blockNumber = undefined,
	isFlashing = false,
	isResizable = false,
	showDelete = false,
	onclick,
	onfocus,
	onpointerenter,
	onpointerleave
}: {
	annotation: Annotation;
	isHovered: boolean;
	isActive: boolean;
	faded?: boolean;
	dimmed?: boolean;
	blockNumber?: number | undefined;
	isFlashing?: boolean;
	isResizable?: boolean;
	showDelete?: boolean;
	onclick: () => void;
	onfocus?: () => void;
	onpointerenter: () => void;
	onpointerleave: () => void;
} = $props();

// When deletion is available (transcribe mode), announce the otherwise-hidden
// Delete affordance to assistive tech (issue #327). The transcribeShortcuts
// action is the single owner of the key itself.
const ariaLabel = $derived(
	showDelete ? m.annotation_label_with_delete() : m.annotation_view_label()
);

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})`;
}

let clipPath = $derived.by(() => {
	if (!annotation.polygon || annotation.polygon.length !== 4) return 'none';
	const points = annotation.polygon
		.map(([px, py]) => {
			const cx = ((px - annotation.x) / annotation.width) * 100;
			const cy = ((py - annotation.y) / annotation.height) * 100;
			return `${cx}% ${cy}%`;
		})
		.join(', ');
	return `polygon(${points})`;
});

let bgAlpha = $derived(dimmed ? 0.3 : isHovered || isActive ? 0.5 : 0.3);

let boxShadow = $derived.by(() => {
	if (dimmed) return 'none';
	if (isActive || isHovered) return `inset 0 0 0 2px ${hexToRgba(annotation.color, 0.8)}`;
	return 'none';
});

let opacity = $derived(dimmed ? 1 : faded ? 0.3 : 1);

let shapeStyle = $derived(
	`position: absolute;` +
		` left: ${annotation.x * 100}%;` +
		` top: ${annotation.y * 100}%;` +
		` width: ${annotation.width * 100}%;` +
		` height: ${annotation.height * 100}%;` +
		` background-color: ${hexToRgba(annotation.color, bgAlpha)};` +
		` box-shadow: ${boxShadow};` +
		` opacity: ${opacity};` +
		` pointer-events: auto;` +
		` cursor: pointer;` +
		` transition: background-color 0.15s ease, box-shadow 0.15s ease, opacity 0.3s ease;` +
		(clipPath !== 'none' ? ` clip-path: ${clipPath};` : '')
);
</script>

<div
	data-testid="annotation-{annotation.id}"
	data-annotation
	class:annotation-flash={isFlashing}
	role="button"
	tabindex="0"
	aria-label={ariaLabel}
	aria-keyshortcuts={showDelete ? 'Delete' : undefined}
	onclick={onclick}
	onfocus={onfocus}
	onkeydown={(e) => {
		if (e.key === 'Enter' || e.key === ' ') onclick();
	}}
	onpointerenter={onpointerenter}
	onpointerleave={onpointerleave}
	style={shapeStyle}
>
	{#if !dimmed && blockNumber}
		<div
			style="
				position: absolute;
				top: -8px;
				left: -8px;
				width: 20px;
				height: 20px;
				border-radius: 50%;
				background-color: {annotation.color};
				color: white;
				font-size: 12px;
				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);
			"
		>
			{blockNumber}
		</div>
	{/if}
	{#if isResizable}
		<AnnotationEditOverlay annotation={annotation} />
	{/if}
</div>

<style>
@keyframes annotation-flash-anim {
	0% {
		outline: 3px solid color-mix(in srgb, var(--color-turquoise) 80%, transparent);
		outline-offset: 0px;
	}
	100% {
		outline: 3px solid color-mix(in srgb, var(--color-turquoise) 0%, transparent);
		outline-offset: 2px;
	}
}

.annotation-flash {
	animation: annotation-flash-anim 1.5s ease-out;
}

@media (prefers-reduced-motion: reduce) {
	.annotation-flash {
		animation: none;
		outline: 3px solid color-mix(in srgb, var(--color-turquoise) 80%, transparent);
	}
}
</style>
