<script lang="ts">
	import { tick } from 'svelte';
	import { GLOBAL_NAV as GLOBAL_CONF } from '$lib/config/shortcuts';
	import { activeShortcuts as store } from '$lib/stores/shortcut-store';

	let { open = false, onClose } = $props();

	// Group local shortcuts
	let localShortcuts = $derived($store.shortcuts);

	let globalList = $state<HTMLDivElement | undefined>();
	let localList = $state<HTMLDivElement | undefined>();
	let modalRef = $state<HTMLDivElement | undefined>();

	const SHORTCUTS_HELP_TITLE_ID = 'shortcuts-help-dialog-title';

	function isFocusableVisible(el: HTMLElement): boolean {
		if (el.hasAttribute('disabled')) return false;
		if (el.tabIndex === -1) return false;
		const rect = el.getBoundingClientRect();
		return rect.width > 0 && rect.height > 0;
	}

	$effect(() => {
		if (!open) return;
		let cancelled = false;
		tick().then(() => {
			requestAnimationFrame(() => {
				if (cancelled) return;
				globalList?.focus();
			});
		});
		return () => {
			cancelled = true;
		};
	});

	function handleArrowScroll(event: KeyboardEvent, target: HTMLDivElement | undefined) {
		if (!target) return;
		if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
			event.preventDefault();
			const delta = event.key === 'ArrowDown' ? 32 : -32;
			target.scrollTop += delta;
		}
	}

	function handleFocusTrap(event: KeyboardEvent) {
		if (event.key !== 'Tab' || !modalRef) return;
		const focusable = modalRef.querySelectorAll<HTMLElement>(
			'button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"])'
		);
		const focusables = Array.from(focusable).filter((el) => isFocusableVisible(el));
		if (focusables.length === 0) return;
		const first = focusables[0];
		const last = focusables[focusables.length - 1];
		const active = document.activeElement as HTMLElement;

		if (!event.shiftKey && active === last) {
			event.preventDefault();
			first.focus();
		} else if (event.shiftKey && active === first) {
			event.preventDefault();
			last.focus();
		}
	}
</script>

{#if open}
	<div
		class="fixed inset-0 z-[100] flex items-center justify-center bg-black/50 backdrop-blur-sm"
		role="dialog"
		aria-modal="true"
		aria-labelledby={SHORTCUTS_HELP_TITLE_ID}
	>
		<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
		<div
			class="max-h-[80vh] w-full max-w-2xl overflow-y-auto rounded-xl bg-white p-6 text-gray-900 shadow-2xl dark:bg-gray-900 dark:text-gray-100"
			role="document"
			bind:this={modalRef}
			onkeydown={handleFocusTrap}
		>
			<div
				class="mb-6 flex items-center justify-between border-b border-gray-200 pb-4 dark:border-gray-800"
			>
				<div>
					<h2 id={SHORTCUTS_HELP_TITLE_ID} class="text-xl font-bold">Keyboard Shortcuts</h2>
					<p class="text-sm text-gray-500 dark:text-gray-400">
						Context: <span class="font-medium text-blue-600 dark:text-blue-400"
							>{$store.context}</span
						>
					</p>
				</div>
				<button onclick={onClose} class="rounded-lg p-2 hover:bg-gray-100 dark:hover:bg-gray-800">
					<span class="sr-only">Close</span>
					<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor"
						><path
							stroke-linecap="round"
							stroke-linejoin="round"
							stroke-width="2"
							d="M6 18L18 6M6 6l12 12"
						/></svg
					>
				</button>
			</div>

			<div class="grid grid-cols-2 gap-8">
				<!-- Global Navigation -->
				<div>
					<h3
						class="mb-3 text-sm font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400"
					>
						Global Navigation (Alt)
					</h3>
					<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
					<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
					<div
						class="max-h-64 space-y-2 overflow-y-auto rounded pr-1 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none"
						role="region"
						aria-label="Global Navigation shortcuts"
						bind:this={globalList}
						tabindex="0"
						onkeydown={(event) => handleArrowScroll(event, globalList)}
					>
						{#each Object.entries(GLOBAL_CONF) as [key, route]}
							<div
								class="flex items-center justify-between rounded bg-gray-50 px-3 py-2 dark:bg-gray-800/50"
							>
								<span class="text-sm font-medium"
									>{key === 'b'
										? 'Search'
										: route === 'SIDEBAR_FOCUS'
											? 'Sidebar menu (focus)'
											: route === 'MAIN_CONTENT_FOCUS'
												? 'Main content (focus first control)'
												: route === '/'
													? 'Home'
													: 'Go to ' + String(route).split('/').pop()}</span
								>
								<kbd
									class="rounded border border-gray-200 bg-white px-2 py-0.5 text-xs font-bold text-gray-700 shadow-sm dark:border-gray-700 dark:bg-gray-800 dark:text-gray-300"
									>Alt + {key.toUpperCase()}</kbd
								>
							</div>
						{/each}
					</div>
				</div>

				<!-- Local Actions -->
				<div>
					<h3
						class="mb-3 text-sm font-semibold tracking-wider text-gray-500 uppercase dark:text-gray-400"
					>
						Active Actions (Alt+Shift)
					</h3>
					{#if localShortcuts.length === 0}
						<p class="text-sm text-gray-400 italic">No specific actions for this view.</p>
					{:else}
						<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
						<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
						<div
							class="max-h-64 space-y-2 overflow-y-auto rounded pr-1 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:outline-none"
							role="region"
							aria-label="Active Actions shortcuts"
							bind:this={localList}
							tabindex="0"
							onkeydown={(event) => handleArrowScroll(event, localList)}
						>
							{#each localShortcuts as shortcut}
								<div
									class="flex items-center justify-between rounded bg-blue-50 px-3 py-2 dark:bg-blue-900/20"
								>
									<span class="text-sm font-medium text-blue-900 dark:text-blue-100"
										>{shortcut.description}</span
									>
									<kbd
										class="rounded border border-blue-200 bg-white px-2 py-0.5 text-xs font-bold text-blue-700 shadow-sm dark:border-blue-800 dark:bg-gray-900 dark:text-blue-300"
										>{shortcut.key}</kbd
									>
								</div>
							{/each}
						</div>
					{/if}
				</div>
			</div>

			<div class="mt-8 flex justify-end border-t border-gray-200 pt-4 dark:border-gray-800">
				<button
					onclick={onClose}
					class="rounded bg-gray-900 px-4 py-2 text-sm font-medium text-white hover:bg-gray-800 dark:bg-white dark:text-gray-900"
					>Close</button
				>
			</div>
		</div>
	</div>
{/if}
