<script lang="ts">
	import { goto } from '$app/navigation';
	import { page } from '$app/stores';
	import { browser } from '$app/environment';
	import { GLOBAL_NAV } from '$lib/config/shortcuts';
	import { shortcutStore, activeShortcutsList } from '$lib/stores/shortcut-store';
	import { focusStore, interactionMode } from '$lib/stores/focus-store';
	import ShortcutsHelpModal from './ShortcutsHelpModal.svelte';

	let showHelp = $state(false);
	let lastShortcutTime = 0;

	// Verificar si el usuario está autenticado
	function isAuthenticated(): boolean {
		if (!browser) return false;
		const currentPath = $page?.url?.pathname || '';
		const isAuthenticatedRoute = currentPath.startsWith('/dashboard');
		const hasAccessToken =
			document.cookie.includes('access_token=') || localStorage.getItem('access_token');
		return isAuthenticatedRoute && !!hasAccessToken;
	}

	function autoFocusFirstInput() {
		// Small delay to allow Svelte to render the new view
		setTimeout(() => {
			const container = document.getElementById('main-form-content') || document.body;

			// 1. Try to find active tab panels (Shadcn/Radix uses role="tabpanel" and data-state="active")
			const activePanels = container.querySelectorAll('[role="tabpanel"][data-state="active"]');

			// If there are panels (can be nested), prioritize the last one (usually the deepest)
			const searchableAreas =
				activePanels.length > 0 ? Array.from(activePanels).reverse() : [container];

			for (const area of searchableAreas) {
				const focusables = area.querySelectorAll(
					'input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]):not([role="tab"])'
				);

				// Find the first one that is actually visible AND not in the sidebar
				const firstVisible = Array.from(focusables).find((el) => {
					const htmlEl = el as HTMLElement;
					// Exclude sidebar elements
					if (htmlEl.closest('[data-sidebar="sidebar"]')) return false;

					return !!(htmlEl.offsetWidth || htmlEl.offsetHeight || htmlEl.getClientRects().length);
				}) as HTMLElement;

				if (firstVisible) {
					firstVisible.focus();
					// Use 'auto' (instant) to avoid interruptions and ensure it actually moves.
					// 'center' is usually best, but if it fails, 'start' can be tried.
					// Use 'smooth' and 'center' to match the global behavior
					setTimeout(() => {
						firstVisible.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
					}, 100);
					return;
				}
			}
		}, 350); // Increased delay to wait for Sheet/Dialog animations (usually ~300ms)
	}

	function focusTriggerByDescription(description: string) {
		// Small delay to allow Svelte to update the DOM
		setTimeout(() => {
			// Extract a meaningful keyword from the description (e.g., "Go to DTA")
			const words = description.split(' ');
			// Look for words that are uppercase or the last word
			const keyword =
				words.find((w) => w.length >= 3 && w === w.toUpperCase()) || words[words.length - 1];

			if (!keyword) return;

			// Find buttons or tabs containing that text
			const elements = document.querySelectorAll('button, [role="tab"], a');
			const target = Array.from(elements).find((el) => {
				const text = el.textContent?.trim() || '';
				// Exclude sidebar
				if (el.closest('[data-sidebar="sidebar"]')) return false;

				return text.toLowerCase().includes(keyword.toLowerCase());
			}) as HTMLElement;

			if (target) {
				target.focus();
				target.scrollIntoView({ behavior: 'smooth', block: 'center' });
			}
		}, 100);
	}

	// FOCUS POLICY DICTIONARY
	// Decides what to focus after a shortcut/navigation based on context
	const FOCUS_POLICY: Record<string, 'trigger' | 'first-input'> = {
		'General Tab Navigation': 'trigger', // Alt + Number focuses the sub-tab button
		'Pedimento Edit Main Tabs': 'first-input', // Alt + Letter focuses first field
		'Otros Tab Navigation': 'first-input', // Alt + Number focuses first field
		'Contribuciones Tab Navigation': 'first-input' // Alt + Number focuses first field
	};

	// Listen for remote focus requests (e.g., from mouse navigation)
	$effect(() => {
		if ($focusStore) {
			// If a shortcut was just pressed, ignore remote focus requests for 250ms
			// to allow the shortcut's specific focus strategy to prevail
			if (Date.now() - lastShortcutTime < 250) return;

			if ($focusStore.strategy === 'first-input') {
				autoFocusFirstInput();
			} else if ($focusStore.strategy === 'trigger' && $focusStore.description) {
				focusTriggerByDescription($focusStore.description);
			}
		}
	});

	function handleKeydown(event: KeyboardEvent) {
		// Verificar autenticación al inicio
		const authenticated = isAuthenticated();

		const { key, altKey, ctrlKey, metaKey, shiftKey } = event;
		if (!key) return;
		const lowerKey = key.toLowerCase();

		// Ignore standalone modifiers
		if (['Control', 'Alt', 'Shift', 'Meta'].includes(key)) return;

		// Construct current combo string: "Alt+Shift+K"
		const modifiers = [];
		if (ctrlKey) modifiers.push('Ctrl');
		if (altKey) modifiers.push('Alt');
		if (shiftKey) modifiers.push('Shift');
		if (metaKey) modifiers.push('Meta');

		const combo = [...modifiers, key.toUpperCase()].join('+');

		// Input Guard
		const target = event.target as HTMLElement;
		const isInput =
			target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;

		// 0. SEARCH TO TABLE FLOW: ArrowDown from search input to first table row
		if (isInput && key === 'ArrowDown') {
			const dialog = target.closest('[role="dialog"]');
			if (dialog) {
				const firstRow = dialog.querySelector(
					'tr[tabindex="0"], [data-slot$="-item"][tabindex="0"]'
				) as HTMLElement;
				if (firstRow) {
					event.preventDefault();
					firstRow.focus();
					return;
				}
			}
		}

		// 1. HELP: F1
		if (key === 'F1') {
			// Solo permitir F1 si está autenticado
			if (!isAuthenticated()) {
				return;
			}
			event.preventDefault();
			showHelp = !showHelp;
			return;
		}

		// 2. ESCAPE
		if (key === 'Escape') {
			if (showHelp) {
				showHelp = false;
				event.preventDefault();
				return;
			}
			// specific search for Escape in REVERSE order (LIFO)
			const match = [...$activeShortcutsList].reverse().find((s) => s.key === 'Escape');
			if (match) {
				event.preventDefault();
				match.action();
				return;
			}
		}

		// 3. PRIORITY: LOCAL SHORTCUTS
		// Solo permitir atajos locales si está autenticado
		if (authenticated) {
			// Match exact combo string against registered shortcuts
			// Search in REVERSE order (LIFO) so recent contexts (modals) override earlier ones (pages)
			const reversedShortcuts = [...$activeShortcutsList].reverse();
			let match = reversedShortcuts.find((s) => s.key === combo);

			// Fallback: If no match found by 'key' (e.g. Shift+1 produces 'Alt+Shift+!'),
			// try matching by 'code' (e.g. 'Alt+Shift+Digit1')
			if (!match) {
				const codeCombo = [...modifiers, event.code].join('+');
				match = reversedShortcuts.find((s) => s.key === codeCombo);
			}

			if (match) {
				// Guard: If it's a single key (no modifiers) and we are in input, ignore it
				// Unless the shortcut explicitly says "allowInInput" (not implemented yet, assuming strictly no inputs for single keys)
				if (modifiers.length === 0 && isInput) {
					// allow native typing
					return;
				}

				event.preventDefault();
				event.stopPropagation(); // Stop bubbling
				lastShortcutTime = Date.now();
				match.action();

				// Hybrid focus strategy
				if (combo.includes('Alt+') && match) {
					const isDigit = combo.includes('Digit') || (event.code && event.code.startsWith('Digit'));
					const strategy = FOCUS_POLICY[match.context] || 'first-input';

					if (isDigit && strategy === 'trigger') {
						// Focus the trigger for specific views (General sub-tabs)
						focusTriggerByDescription(match.description);
					} else {
						// Default: Focus the first input (Main tabs, non-trigger sub-tabs)
						autoFocusFirstInput();
					}
				}
				return;
			}
		} // Fin del bloque authenticated

		// 4. GLOBAL NAV: Alt + Key (Legacy/Default behavior for global nav)
		// Solo permitir si está autenticado
		if (authenticated && altKey && modifiers.length === 1) {
			// Exactly Alt + Key (no shift/ctrl)
			// Special: Alt+B -> Focus Search
			if (lowerKey === 'b') {
				event.preventDefault();
				const searchInput = document.getElementById('global-search-input');
				searchInput?.focus();
				return;
			}

			const route = GLOBAL_NAV[lowerKey as keyof typeof GLOBAL_NAV];
			if (route) {
				event.preventDefault();
				goto(route);
				return;
			}
		}

		// 5. GLOBAL TABLE & SELECT NAVIGATION: Arrows / Enter / Tab
		const isRowOrItem =
			target.tagName === 'TR' ||
			target.getAttribute('data-slot') === 'table-row' ||
			target.getAttribute('data-slot') === 'select-item' ||
			target.closest('[data-slot="table-row"]') ||
			target.closest('[data-slot="select-item"]');

		if (isRowOrItem) {
			const element = (
				target.getAttribute('data-slot')?.includes('-item') || target.tagName === 'TR'
					? target
					: target.closest('[data-slot$="-row"], [data-slot$="-item"]')
			) as HTMLElement;

			if (!element) return;

			// Logic for UP/DOWN arrows
			if (key === 'ArrowDown') {
				const next = element.nextElementSibling as HTMLElement;
				if (next) {
					event.preventDefault();
					next.focus();
				}
			} else if (key === 'ArrowUp') {
				const prev = element.previousElementSibling as HTMLElement;
				if (prev) {
					event.preventDefault();
					prev.focus();
				}
			} else if (key === 'Enter' || key === ' ') {
				if (target.tagName !== 'INPUT' && target.tagName !== 'TEXTAREA') {
					event.preventDefault();
					element.click();
				}
			} else if (key === 'Tab') {
				// Custom Tab navigation for rows/items if requested
				const siblings = Array.from(element.parentElement?.children || []);
				const index = siblings.indexOf(element);

				if (shiftKey) {
					if (index > 0) {
						event.preventDefault();
						(siblings[index - 1] as HTMLElement).focus();
					}
				} else {
					if (index < siblings.length - 1) {
						event.preventDefault();
						(siblings[index + 1] as HTMLElement).focus();
					}
				}
			}
		}
	}

	function handleFocusIn(event: FocusEvent) {
		const target = event.target as HTMLElement;
		if (!target) return;

		// Exclude sidebar from any magic scrolling
		if (target.closest('[data-sidebar="sidebar"]')) return;

		// Check if it's an interactive element we care about
		const isInteractive =
			['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'A'].includes(target.tagName) ||
			target.role === 'tab' ||
			target.tagName === 'TR';

		if (isInteractive) {
			// Force scroll to center after a delay to override browser default behavior
			setTimeout(() => {
				target.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
			}, 100);
		}
	}
	// --- DYNAMIC INTERACTIVE OBSERVER ---
	// Automatically make any clickable row or item focusable
	$effect(() => {
		const observer = new MutationObserver((mutations) => {
			mutations.forEach((mutation) => {
				mutation.addedNodes.forEach((node) => {
					if (node instanceof HTMLElement) {
						// Find TRs that look like they are clickable/interactive
						const trs = node.tagName === 'TR' ? [node] : Array.from(node.querySelectorAll('tr'));
						trs.forEach((tr) => {
							// If it has a cursor-pointer class or an onclick handler (complex to detect in Svelte,
							// so we use a broad heuristic: any TR inside a dialog's scroll area)
							const isInSelectionDialog =
								!!tr.closest('[role="dialog"]') && !!tr.closest('.overflow-y-auto');
							if (isInSelectionDialog && !tr.hasAttribute('tabindex')) {
								tr.setAttribute('tabindex', '0');
								// Add focus styles if it's a native TR
								if (!tr.getAttribute('data-slot')) {
									tr.classList.add(
										'focus-visible:outline-none',
										'focus-visible:bg-accent',
										'focus-visible:ring-1',
										'focus-visible:ring-ring'
									);
								}
							}
						});
					}
				});
			});
		});

		observer.observe(document.body, { childList: true, subtree: true });
		return () => observer.disconnect();
	});
</script>

<svelte:window
	onkeydown={(e) => {
		interactionMode.set('keyboard');
		handleKeydown(e);
	}}
	onmousedown={() => interactionMode.set('mouse')}
	onfocusin={handleFocusIn}
/>

{#if showHelp}
	<ShortcutsHelpModal open={true} onClose={() => (showHelp = false)} />
{/if}
