/**
 * Terminal Keyboard Handler
 * 
 * Handles keyboard navigation and interaction for the terminal.
 */

import type { DisplayedLine } from './types';
import { browser } from '$app/environment';
import { goto } from '$app/navigation';

export interface KeyboardHandlerOptions {
	getIsTyping: () => boolean;
	getIsComplete: () => boolean;
	getInteractive: () => boolean;
	getButtonIndices: () => number[];
	getSelectedIndex: () => number;
	setSelectedIndex: (index: number) => void;
	getDisplayedLines: () => DisplayedLine[];
	getBodyElement: () => HTMLDivElement | undefined;
	skipAnimation: () => void;
	scrollMargin?: number;
}

/**
 * Scroll selected button into view with margin for context
 */
export function scrollToSelected(
	bodyElement: HTMLDivElement | undefined,
	selectedIndex: number,
	displayedLines: DisplayedLine[],
	scrollMargin: number = 80
): void {
	if (!bodyElement || selectedIndex < 0) return;

	// Get all buttons in DOM order (including nested ones in groups)
	const allButtons = bodyElement.querySelectorAll('.tui-button');
	const selectedButton = allButtons[selectedIndex] as HTMLElement | undefined;

	if (selectedButton && bodyElement) {
		const containerRect = bodyElement.getBoundingClientRect();
		const buttonRect = selectedButton.getBoundingClientRect();

		if (buttonRect.top < containerRect.top + scrollMargin) {
			const scrollAmount = buttonRect.top - containerRect.top - scrollMargin;
			bodyElement.scrollBy({ top: scrollAmount, behavior: 'smooth' });
		} else if (buttonRect.bottom > containerRect.bottom - scrollMargin) {
			const scrollAmount = buttonRect.bottom - containerRect.bottom + scrollMargin;
			bodyElement.scrollBy({ top: scrollAmount, behavior: 'smooth' });
		}
	}
}

/**
 * Handle button/link click navigation
 */
export function handleNavigation(line: { action?: () => void; href?: string; external?: boolean } | undefined): void {
	if (!line) return;

	if (line.action) {
		line.action();
	} else if (line.href) {
		const isExternal = line.external || line.href.startsWith('http://') || line.href.startsWith('https://');
		if (isExternal) {
			window.open(line.href, '_blank', 'noopener,noreferrer');
		} else {
			// Use SvelteKit's goto for client-side navigation (no page reload)
			goto(line.href);
		}
	}
}

/**
 * Create a keyboard event handler for the terminal
 */
export function createKeyboardHandler(options: KeyboardHandlerOptions) {
	const {
		getIsTyping,
		getIsComplete,
		getInteractive,
		getButtonIndices,
		getSelectedIndex,
		setSelectedIndex,
		getDisplayedLines,
		getBodyElement,
		skipAnimation,
		scrollMargin = 80
	} = options;

	return function handleKeydown(event: KeyboardEvent): void {
		// Skip animation on Y key
		if (getIsTyping() && (event.key === 'y' || event.key === 'Y')) {
			event.preventDefault();
			skipAnimation();
			return;
		}

		if (!getInteractive() || !getIsComplete()) return;

		const bodyElement = getBodyElement();
		if (!bodyElement) return;

		// Get all buttons from the DOM (including nested ones in groups)
		const allButtons = bodyElement.querySelectorAll('.tui-button');
		const buttonCount = allButtons.length;
		if (buttonCount === 0) return;

		const selectedIndex = getSelectedIndex();
		const displayedLines = getDisplayedLines();

		if (event.key === 'ArrowDown' || event.key === 'j') {
			event.preventDefault();
			const nextIdx = selectedIndex < 0 ? 0 : (selectedIndex + 1) % buttonCount;
			setSelectedIndex(nextIdx);
			scrollToSelected(bodyElement, nextIdx, displayedLines, scrollMargin);
			// Update visual selection on buttons
			allButtons.forEach((btn, i) => btn.classList.toggle('selected', i === nextIdx));
		} else if (event.key === 'ArrowUp' || event.key === 'k') {
			event.preventDefault();
			const prevIdx = selectedIndex < 0 ? buttonCount - 1 : (selectedIndex - 1 + buttonCount) % buttonCount;
			setSelectedIndex(prevIdx);
			scrollToSelected(bodyElement, prevIdx, displayedLines, scrollMargin);
			// Update visual selection on buttons
			allButtons.forEach((btn, i) => btn.classList.toggle('selected', i === prevIdx));
		} else if (event.key === 'Enter') {
			event.preventDefault();
			if (selectedIndex >= 0 && selectedIndex < buttonCount) {
				const selectedButton = allButtons[selectedIndex] as HTMLElement;
				if (selectedButton) {
					// Read navigation data from button data attributes
					const href = selectedButton.dataset.href;
					const isExternal = selectedButton.dataset.external === 'true';
					
					if (href) {
						handleNavigation({ href, external: isExternal });
					} else {
						// Fallback to click for buttons with actions (non-navigational)
						selectedButton.click();
					}
				}
			}
		}
	};
}

/**
 * Scroll to hash target (anchor link like #skills)
 */
export function scrollToHash(bodyElement: HTMLDivElement | undefined): void {
	if (!browser || !bodyElement) return;

	const hash = window.location.hash;
	if (!hash) return;

	const targetId = hash.slice(1); // Remove the #
	const targetElement = bodyElement.querySelector(`#${CSS.escape(targetId)}`);

	if (targetElement) {
		// Small delay to ensure layout is complete
		setTimeout(() => {
			targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
		}, 100);
	}
}
