import { useDebouncedCallback } from "use-debounce";
import { useCallback } from "react";
import { toast } from "sonner";
import { matchesKeyboardBinding, } from "../commands/commands";
export function useKeyboardNavigation(deps) {
    const { editContextRef, keyboardCommands, executeCommand, showQuickSwitcher, cycleQuickSwitcher, } = deps;
    const handleKeyDownDebounced = useDebouncedCallback(async (event) => {
        const editContext = editContextRef.current;
        if (!editContext)
            return;
        if (event.ctrlKey && event.key === "F11") {
            console.log("F11 pressed");
            event.preventDefault();
            if (!editContext.configuration.forceFullscreen) {
                editContext.setFullscreen(false);
            }
        }
        // Quick access to favorites (Ctrl + Alt + 1-9)
        if (event.ctrlKey && event.altKey && /^[1-9]$/.test(event.key)) {
            event.preventDefault();
            const index = parseInt(event.key) - 1;
            // Use favorites from editContext
            if (editContext.favorites) {
                const favorites = editContext.favorites;
                if (favorites[index]) {
                    const favorite = favorites[index];
                    editContext.loadItem({
                        id: favorite.itemId,
                        language: favorite.language,
                        version: 0,
                    });
                }
                else {
                    toast.info(`No favorite item at position ${event.key}`);
                }
            }
            else {
                toast.info("Favorites not loaded yet");
            }
            return;
        }
        // Command execution
        const command = keyboardCommands.find((candidate) => matchesKeyboardBinding(event, candidate.keyBinding));
        if (command) {
            // Check if user is typing in an input field
            const isTyping = isTypingEventTarget(event);
            // Don't execute commands when typing in text fields
            // F2 works everywhere except when typing
            // Delete also won't trigger when typing
            if (isTyping)
                return;
            const keyboardData = {
                source: "keyboard",
            };
            const isItemCommand = editContext.configuration.commands.allItemCommands.some((itemCommand) => itemCommand.id === command.id);
            if (isItemCommand) {
                const currentItem = editContext.item;
                if (!currentItem)
                    return;
                const items = editContext.selection?.map((selectionId) => ({
                    id: selectionId,
                    language: currentItem.language,
                    version: 0,
                })) || [];
                if (!items.length)
                    items.push(currentItem.descriptor);
                if (items.length === 0)
                    return;
                keyboardData.items =
                    await editContext.itemsRepository.getItems(items);
            }
            if (editContext.isCommandDisabled({
                command: command,
                data: keyboardData,
            })) {
                return;
            }
            event.preventDefault();
            event.stopPropagation();
            await executeCommand({
                command,
                data: keyboardData,
            });
        }
    }, 50);
    const handleKeyDown = useCallback(async (event) => {
        // EARLY EXIT: Don't interfere with text selection/navigation in input fields
        // This ensures Shift+Arrow, Arrow keys, Home, End, etc. work for text selection
        const isTypingNow = isTypingEventTarget(event);
        if (isTypingNow) {
            // Allow basic text navigation and selection keys to pass through
            const textNavKeys = [
                "ArrowLeft",
                "ArrowRight",
                "ArrowUp",
                "ArrowDown",
                "Home",
                "End",
                "PageUp",
                "PageDown",
            ];
            if (textNavKeys.includes(event.key)) {
                // Let the browser handle text navigation/selection natively
                return;
            }
        }
        if (event.key === "Insert") {
            event.preventDefault();
            event.stopPropagation();
            editContextRef.current?.setInsertMode((x) => !x);
        }
        if (event.ctrlKey && event.key === "s") {
            event.preventDefault();
            event.stopPropagation();
            return;
        }
        // Check if quick switcher is currently visible
        const isQuickSwitcherVisible = editContextRef.current
            ? editContextRef.current.isQuickSwitcherVisible
            : false;
        // Handle navigation keys when switcher is visible (check this FIRST)
        if (isQuickSwitcherVisible && editContextRef.current) {
            // Q key (or Ctrl+Q) cycles to next entry for easy one-handed navigation
            if (event.key.toLowerCase() === "q") {
                console.log(`[KeyNav] Q pressed - moving to next entry`);
                event.preventDefault();
                event.stopPropagation();
                cycleQuickSwitcher?.("next");
                return;
            }
            // Arrow keys for navigation
            if (event.key === "ArrowLeft" ||
                event.key === "ArrowRight" ||
                event.key === "ArrowUp" ||
                event.key === "ArrowDown") {
                console.log(`[KeyNav] Arrow key navigation: ${event.key}`);
                event.preventDefault();
                event.stopPropagation();
                let direction;
                switch (event.key) {
                    case "ArrowLeft":
                        direction = "prev";
                        break;
                    case "ArrowRight":
                        direction = "next";
                        break;
                    case "ArrowUp":
                        direction = "up";
                        break;
                    case "ArrowDown":
                        direction = "down";
                        break;
                }
                cycleQuickSwitcher?.(direction);
                return;
            }
            // Enter or Escape to close
            if (event.key === "Enter" || event.key === "Escape") {
                console.log(`[KeyNav] ${event.key} pressed - closing switcher with selection: ${event.key === "Enter"}`);
                event.preventDefault();
                event.stopPropagation();
                // showQuickSwitcher(false) will be handled by the Enter key handler in EditorShell
                // For now, we just let the keyup handler in EditorShell handle it
                return;
            }
        }
        // Handle quick switcher trigger (Ctrl+Q) - only if NOT already visible
        if (!isQuickSwitcherVisible &&
            (event.ctrlKey || event.metaKey) &&
            event.key.toLowerCase() === "q" &&
            editContextRef.current) {
            console.log("[KeyNav] Quick switcher trigger: Ctrl+Q");
            event.preventDefault();
            event.stopPropagation();
            showQuickSwitcher?.(true);
            return;
        }
        if (keyboardCommands.length === 0) {
            return;
        }
        const isTyping = isTypingEventTarget(event);
        // Clipboard operations (Ctrl+C, Ctrl+X, Ctrl+V) - only when not typing
        const clipboardKey = (event.key || "").toLowerCase();
        const isClipboardShortcut = clipboardKey === "c" || clipboardKey === "x" || clipboardKey === "v";
        if ((event.ctrlKey || event.metaKey) &&
            !isTyping &&
            editContextRef.current &&
            isClipboardShortcut) {
            const activeEl = typeof document !== "undefined"
                ? document.activeElement
                : null;
            // Only allow content-tree clipboard shortcuts when focus is within the content tree.
            const isInContentTree = !!event.target?.closest?.('[data-parhelia-content-tree="true"]') || !!activeEl?.closest?.('[data-parhelia-content-tree="true"]');
            if (!isInContentTree)
                return;
            const ctx = editContextRef.current;
            const currentItem = ctx.item;
            // Ctrl+C - Copy selected items to clipboard
            if (event.key?.toLowerCase() === "c") {
                if (!currentItem)
                    return;
                const selectedIds = ctx.contentTreeSelection && ctx.contentTreeSelection.length > 0
                    ? ctx.contentTreeSelection
                    : [currentItem.id];
                const items = selectedIds.map((id) => ({
                    id,
                    language: currentItem.language,
                    version: 0,
                }));
                ctx.setClipboard({ items, operation: "copy" });
                toast.success(`${items.length} item${items.length > 1 ? "s" : ""} copied`);
                event.preventDefault();
                event.stopPropagation();
                return;
            }
            // Ctrl+X - Cut selected items to clipboard
            if (event.key?.toLowerCase() === "x") {
                if (!currentItem)
                    return;
                const selectedIds = ctx.contentTreeSelection && ctx.contentTreeSelection.length > 0
                    ? ctx.contentTreeSelection
                    : [currentItem.id];
                const items = selectedIds.map((id) => ({
                    id,
                    language: currentItem.language,
                    version: 0,
                }));
                ctx.setClipboard({ items, operation: "cut" });
                toast.success(`${items.length} item${items.length > 1 ? "s" : ""} cut`);
                event.preventDefault();
                event.stopPropagation();
                return;
            }
            // Ctrl+V - Paste items from clipboard
            if (event.key?.toLowerCase() === "v") {
                const clipboard = ctx.clipboard;
                if (!clipboard || !currentItem)
                    return;
                event.preventDefault();
                event.stopPropagation();
                const targetItem = currentItem.descriptor;
                // Get full items from clipboard descriptors
                const fullItems = await ctx.itemsRepository.getItems(clipboard.items);
                if (!fullItems || fullItems.length === 0) {
                    toast.error("Clipboard items no longer exist");
                    ctx.setClipboard(null);
                    return;
                }
                if (clipboard.operation === "copy") {
                    // Copy items to target
                    const command = ctx.configuration.commands.copyItems;
                    if (command) {
                        await executeCommand({
                            command,
                            data: {
                                items: fullItems,
                                targetItem,
                                index: -1,
                            },
                        });
                        toast.success(`${fullItems.length} item${fullItems.length > 1 ? "s" : ""} pasted`);
                    }
                }
                else {
                    // Move items to target (cut)
                    const command = ctx.configuration.commands.moveItems;
                    if (command) {
                        await executeCommand({
                            command,
                            data: {
                                items: fullItems,
                                targetItem,
                                index: -1,
                            },
                        });
                        toast.success(`${fullItems.length} item${fullItems.length > 1 ? "s" : ""} moved`);
                        // Clear clipboard after cut/paste
                        ctx.setClipboard(null);
                    }
                }
                return;
            }
        }
        handleKeyDownDebounced(event);
    }, [
        handleKeyDownDebounced,
        editContextRef,
        keyboardCommands,
        showQuickSwitcher,
        cycleQuickSwitcher,
    ]);
    return { handleKeyDown };
}
/** True when the event target is an editable field (typing should take precedence over shortcuts). */
export function isTypingEventTarget(event) {
    const target = event.target;
    if (!target)
        return false;
    // If a text node fired the event, use its parent element.
    const maybeNode = target;
    const el = typeof maybeNode.nodeType === "number" && maybeNode.nodeType === 3
        ? maybeNode.parentElement
        : target;
    if (!el)
        return false;
    const htmlEl = el;
    const tag = htmlEl.tagName?.toLowerCase?.() || "";
    // Cross-iframe safe: avoid instanceof checks (different JS realms).
    if (tag === "input" || tag === "textarea" || tag === "select")
        return true;
    if (htmlEl.isContentEditable)
        return true;
    const closestEditable = htmlEl.closest?.('input,textarea,select,[contenteditable=""],[contenteditable="true"],[role="textbox"]');
    return !!closestEditable;
}
//# sourceMappingURL=keyboardNavigation.js.map