"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useTableKeyboardNav = useTableKeyboardNav;
const react_1 = require("react");
const hooks_1 = require("../../../utils/hooks");
const table_cell_1 = require("../helpers/table-cell");
const table_focus_1 = require("../helpers/table-focus");
const table_grid_nav_1 = require("../helpers/table-grid-nav");
const table_keyboard_1 = require("../helpers/table-keyboard");
const useGridCache_1 = require("./useGridCache");
function useTableKeyboardNav({ enabled }) {
    const [tableRef, setTableRef] = (0, react_1.useState)(null);
    const { getTableGrid, activeCell, setActiveCell } = (0, useGridCache_1.useGridCache)(tableRef, enabled);
    /**
     * Executes a navigation action and returns the target cell.
     */
    const executeNavigationAction = (0, hooks_1.useEventCallback)((action) => {
        if (!tableRef) {
            return null;
        }
        let currentCell = activeCell;
        currentCell !== null && currentCell !== void 0 ? currentCell : (currentCell = (0, table_cell_1.focusInitialTableTarget)(tableRef));
        if (!currentCell) {
            return null;
        }
        const { grid, positions } = getTableGrid(tableRef);
        const currentPos = positions.get(currentCell);
        let nextCell = null;
        switch (action.type) {
            case "delta": {
                if (!currentPos) {
                    return null;
                }
                nextCell = (0, table_grid_nav_1.findNextFocusableCell)(grid, currentPos, action.delta, currentCell);
                break;
            }
            case "home": {
                if (!currentPos) {
                    return null;
                }
                nextCell = (0, table_grid_nav_1.findFirstCellInRow)(grid, currentPos.y);
                break;
            }
            case "end": {
                if (!currentPos) {
                    return null;
                }
                nextCell = (0, table_grid_nav_1.findLastCellInRow)(grid, currentPos.y);
                break;
            }
            case "tableStart": {
                nextCell = (0, table_grid_nav_1.findFirstCell)(grid);
                break;
            }
            case "tableEnd": {
                nextCell = (0, table_grid_nav_1.findLastCell)(grid);
                break;
            }
        }
        if (!nextCell || nextCell === currentCell) {
            return null;
        }
        return (0, table_focus_1.focusCellAndUpdateTabIndex)(nextCell, currentCell);
    });
    /**
     * Handles keyboard navigation with arrow keys, Home/End, and PageUp/PageDown.
     * Checks if navigation should be blocked based on current focus context.
     */
    const handleTableKeyDown = (0, hooks_1.useEventCallback)((event) => {
        const action = (0, table_keyboard_1.getNavigationAction)(event);
        if (!action) {
            return;
        }
        if ((0, table_keyboard_1.shouldBlockNavigation)(event)) {
            return;
        }
        event.preventDefault();
        const newCell = executeNavigationAction(action);
        newCell && setActiveCell(newCell);
    });
    /**
     * When focus is moved to elements inside a cell like inputs, checkbox etc
     * we want to update the active cell to the parent td/th, so that keyboard navigation continues to work as expected from there.
     * Make sure td/th elements have tabIndex={-1} so they can receive focus on click
     */
    const handleTableFocusIn = (0, hooks_1.useEventCallback)((event) => {
        var _a;
        const target = event.target;
        if (tableRef && target === tableRef) {
            if (activeCell) {
                (0, table_focus_1.focusCell)(activeCell);
                return;
            }
            (0, table_cell_1.focusInitialTableTarget)(tableRef);
            return;
        }
        const newCell = (_a = target === null || target === void 0 ? void 0 : target.closest("td, th")) !== null && _a !== void 0 ? _a : null;
        if (!newCell || newCell === activeCell) {
            return;
        }
        const updatedCell = (0, table_focus_1.focusCellAndUpdateTabIndex)(newCell, activeCell, {
            shouldFocus: false,
        });
        if (updatedCell) {
            setActiveCell(updatedCell);
        }
    });
    /**
     * Attach event listeners for keyboard navigation and focus management.
     */
    (0, react_1.useEffect)(() => {
        if (!tableRef || !enabled) {
            return;
        }
        tableRef.addEventListener("keydown", handleTableKeyDown);
        tableRef.addEventListener("focusin", handleTableFocusIn);
        return () => {
            tableRef.removeEventListener("keydown", handleTableKeyDown);
            tableRef.removeEventListener("focusin", handleTableFocusIn);
        };
    }, [tableRef, handleTableKeyDown, handleTableFocusIn, enabled]);
    return {
        /* Table should only have tabIndex until the focus is moved inside and is enabled */
        tabIndex: enabled ? 0 : undefined,
        setTableRef,
    };
}
//# sourceMappingURL=useTableKeyboardNav.js.map