<script module>
// Module-level counter produces stable, predictable IDs across SSR + hydration.
// Math.random() would generate different values server-side vs client-side,
// causing a hydration mismatch on first render.
let _counter = 0;
</script>

<script lang="ts">
import type { Snippet } from 'svelte';

type Placement = 'bottom' | 'top' | 'left' | 'right';

type Props = {
	label: string;
	placement?: Placement;
	children?: Snippet;
};

let { label, placement = 'bottom', children }: Props = $props();

const popoverId = `help-popover-${_counter++}`;

let open = $state(false);
let triggerEl: HTMLButtonElement | null = $state(null);

function toggle() {
	open = !open;
}

function close() {
	open = false;
	triggerEl?.focus();
}

$effect(() => {
	if (!open) return;

	function onKeyDown(e: KeyboardEvent) {
		if (e.key === 'Escape') {
			e.preventDefault();
			close();
		}
	}

	function onPointerDown(e: PointerEvent) {
		if (triggerEl && (e.target === triggerEl || triggerEl.contains(e.target as Node))) return;
		const popoverEl = document.getElementById(popoverId);
		if (popoverEl && popoverEl.contains(e.target as Node)) return;
		open = false;
	}

	document.addEventListener('keydown', onKeyDown);
	document.addEventListener('pointerdown', onPointerDown);
	return () => {
		document.removeEventListener('keydown', onKeyDown);
		document.removeEventListener('pointerdown', onPointerDown);
	};
});

const placementClass: Record<Placement, string> = {
	bottom: 'top-full mt-1.5 left-1/2 -translate-x-1/2',
	top: 'bottom-full mb-1.5 left-1/2 -translate-x-1/2',
	left: 'right-full mr-1.5 top-1/2 -translate-y-1/2',
	right: 'left-full ml-1.5 top-1/2 -translate-y-1/2'
};
</script>

<div class="relative inline-block">
	<!--
		Outer button is 44×44px for WCAG 2.5.8 touch-target compliance (our transcriber
		audience is 60+). The inner <span> carries the visual 20×20px circle.
	-->
	<button
		bind:this={triggerEl}
		type="button"
		aria-label={label}
		aria-expanded={open}
		aria-controls={popoverId}
		onclick={toggle}
		class="group flex h-[44px] w-[44px] items-center justify-center rounded-full focus-visible:ring-2 focus-visible:ring-brand-navy"
	>
		<span
			class="flex h-5 w-5 items-center justify-center rounded-full border border-line bg-muted font-sans text-[10px] font-bold text-ink-3 transition-colors group-hover:border-brand-navy group-hover:text-brand-navy"
		>
			?
		</span>
	</button>

	{#if open}
		<div
			id={popoverId}
			role="region"
			aria-label={label}
			class="absolute z-50 w-64 rounded-sm border border-line bg-white p-3 font-sans text-sm text-ink shadow-md {placementClass[placement]}"
		>
			{#if children}
				{@render children()}
			{/if}
		</div>
	{/if}
</div>
