"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get keys () {
        return keys;
    },
    get useKeyNavigation () {
        return useKeyNavigation;
    }
});
const JUMP_SIZE = 10;
const keys = {
    Enter: 'Enter',
    Space: 'Space',
    Tab: 'Tab',
    Escape: 'Escape',
    ArrowLeft: 'ArrowLeft',
    ArrowRight: 'ArrowRight',
    ArrowUp: 'ArrowUp',
    ArrowDown: 'ArrowDown',
    Home: 'Home',
    End: 'End',
    PageUp: 'PageUp',
    PageDown: 'PageDown'
};
const getFurtherPath = (focusedPath, focusedToValueMap)=>{
    const focusedPathAsString = focusedPath.reduce((acc, n)=>`${acc}/${n}`, '').replace(/^(\/)/, '');
    return focusedToValueMap.get(focusedPathAsString);
};
const useKeyNavigation = ({ focusedPath, dispatchFocusedPath, path, dispatchPath, pathMap, focusedToValueMap, handleGlobalToggle, closeOnSelect, onItemSelect, disabled })=>{
    const currentIndex = focusedPath?.[focusedPath.length - 1] || 0;
    const currentLength = pathMap.get(path?.[focusedPath.length - 1]) || 0;
    const onKeyDown = (event)=>{
        if (disabled) {
            return;
        }
        switch(event.code){
            case keys.ArrowUp:
                {
                    if (focusedPath.length) {
                        if (currentIndex > 0) {
                            if (path.length > focusedPath.length) {
                                dispatchPath({
                                    type: 'removed_last_level'
                                });
                            }
                            dispatchFocusedPath({
                                type: 'change_last_focus',
                                value: currentIndex - 1
                            });
                        }
                    } else {
                        dispatchPath({
                            type: 'opened_first_level'
                        });
                        dispatchFocusedPath({
                            type: 'set_initial_focus'
                        });
                        handleGlobalToggle(true, event);
                    }
                    break;
                }
            case keys.ArrowDown:
                {
                    if (focusedPath.length) {
                        if (currentIndex + 1 < currentLength) {
                            if (path.length > focusedPath.length) {
                                dispatchPath({
                                    type: 'removed_last_level'
                                });
                            }
                            dispatchFocusedPath({
                                type: 'change_last_focus',
                                value: currentIndex + 1
                            });
                        }
                    } else {
                        dispatchPath({
                            type: 'opened_first_level'
                        });
                        dispatchFocusedPath({
                            type: 'set_initial_focus'
                        });
                        handleGlobalToggle(true, event);
                    }
                    break;
                }
            case keys.ArrowLeft:
                {
                    if (focusedPath.length) {
                        if (path.length > focusedPath.length) {
                            dispatchPath({
                                type: 'removed_last_level'
                            });
                        } else {
                            dispatchFocusedPath({
                                type: 'return_prev_focus'
                            });
                        }
                    }
                    if (path.length === 1) {
                        handleGlobalToggle(false, event);
                    }
                    break;
                }
            case keys.ArrowRight:
                {
                    if (!focusedPath.length) {
                        break;
                    }
                    const currentItem = getFurtherPath(focusedPath, focusedToValueMap);
                    if (currentItem?.disabled) {
                        break;
                    }
                    if (currentItem?.items) {
                        if (path.length > focusedPath.length) {
                            dispatchFocusedPath({
                                type: 'add_focus',
                                value: 0
                            });
                        } else {
                            dispatchPath({
                                type: 'added_next_level',
                                value: currentItem.value.toString()
                            });
                        }
                    }
                    break;
                }
            case keys.Enter:
            case keys.Space:
                {
                    event.preventDefault();
                    if (!path[0]) {
                        dispatchPath({
                            type: 'opened_first_level'
                        });
                        dispatchFocusedPath({
                            type: 'set_initial_focus'
                        });
                        handleGlobalToggle(true, event);
                        break;
                    }
                    const currentItem = getFurtherPath(focusedPath, focusedToValueMap);
                    if (currentItem?.disabled) {
                        break;
                    }
                    if (currentItem?.items) {
                        if (path.length > focusedPath.length) {
                            dispatchFocusedPath({
                                type: 'add_focus',
                                value: 0
                            });
                        } else {
                            dispatchPath({
                                type: 'added_next_level',
                                value: currentItem.value.toString()
                            });
                        }
                    } else {
                        if (closeOnSelect) {
                            handleGlobalToggle(false, event);
                        }
                        if (onItemSelect && currentItem) {
                            onItemSelect(currentItem, event);
                        }
                    }
                    break;
                }
            case keys.Tab:
            case keys.Escape:
                {
                    if (path[0]) {
                        handleGlobalToggle(false, event);
                    }
                    break;
                }
            case keys.Home:
                {
                    if (path[0]) {
                        if (path.length > focusedPath.length) {
                            dispatchPath({
                                type: 'removed_last_level'
                            });
                        }
                        dispatchFocusedPath({
                            type: 'change_last_focus',
                            value: 0
                        });
                    } else {
                        dispatchPath({
                            type: 'opened_first_level'
                        });
                        dispatchFocusedPath({
                            type: 'set_initial_focus'
                        });
                        handleGlobalToggle(true, event);
                    }
                    break;
                }
            case keys.End:
                {
                    if (path[0]) {
                        if (path.length > focusedPath.length) {
                            dispatchPath({
                                type: 'removed_last_level'
                            });
                        }
                        dispatchFocusedPath({
                            type: 'change_last_focus',
                            value: currentLength - 1
                        });
                    } else {
                        dispatchPath({
                            type: 'opened_first_level'
                        });
                        dispatchFocusedPath({
                            type: 'change_last_focus',
                            value: (pathMap.get('root') || 0) - 1
                        });
                        handleGlobalToggle(true, event);
                    }
                    break;
                }
            case keys.PageUp:
                {
                    if (!path[0]) {
                        break;
                    }
                    if (path.length > focusedPath.length) {
                        dispatchPath({
                            type: 'removed_last_level'
                        });
                    }
                    if (currentIndex <= JUMP_SIZE) {
                        dispatchFocusedPath({
                            type: 'change_last_focus',
                            value: 0
                        });
                    } else {
                        dispatchFocusedPath({
                            type: 'change_last_focus',
                            value: currentIndex - JUMP_SIZE
                        });
                    }
                    break;
                }
            case keys.PageDown:
                {
                    if (!path[0]) {
                        break;
                    }
                    if (path.length > focusedPath.length) {
                        dispatchPath({
                            type: 'removed_last_level'
                        });
                    }
                    if (currentLength - currentIndex <= JUMP_SIZE) {
                        dispatchFocusedPath({
                            type: 'change_last_focus',
                            value: currentLength - 1
                        });
                    } else {
                        dispatchFocusedPath({
                            type: 'change_last_focus',
                            value: currentIndex + JUMP_SIZE
                        });
                    }
                    break;
                }
            default:
                {
                    break;
                }
        }
    };
    return {
        onKeyDown
    };
};
