import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
import { useEffect, useRef } from 'react';
import { Shortcuts } from 'shortcuts';
import { useAfterInitialEffect, useSimpleStore } from '../../hooks';
import { hasProp } from '../../utils';
import { actionStore } from './Store';
/**
 * Function to register an action triggerable using a shortcut. All actions must be registered before
 * binding a callback.
 * @param actions actions with definitions to be registered.
 */
export const registerAction = (...actions) => {
    actionStore.setStore(store => {
        let newStore = store;
        actions.forEach(({ id, defaultKeyBinding: defaultShortcut }) => {
            if (!hasProp(store, id))
                newStore = {
                    ...newStore,
                    [id]: { defaultKeyBinding: defaultShortcut, keyBinding: defaultShortcut }
                };
        });
        return newStore;
    });
};
const dispatchShortcutEvent = (actionId, e) => {
    const shortcutEvent = new CustomEvent('shortcut', {
        bubbles: true,
        detail: { actionId }
    });
    e.target?.dispatchEvent(shortcutEvent);
};
const ShortcutManager = ({ children, target, bindings: customBindings = {} }) => {
    const shortcutsRef = useRef();
    const [bindings, setBindings] = useSimpleStore(actionStore, store => Object.entries(store).map(([actionId, actionDefinition]) => ({
        action: actionId,
        shortcut: actionDefinition.keyBinding
    })));
    useEffect(() => {
        setBindings(store => {
            let newStore = store;
            Object.entries(customBindings).forEach(([actionId, keyBinding]) => {
                newStore = { ...newStore, [actionId]: { ...newStore[actionId], keyBinding } };
            });
            return newStore;
        });
    }, [JSON.stringify(customBindings)]);
    useEffect(() => {
        shortcutsRef.current = new Shortcuts({
            target,
            shouldHandleEvent: e => 
            // both 'keydown' and 'keypress' events are handled by default ('shortcuts' bug?)
            e.type === 'keydown' &&
                !e.defaultPrevented &&
                // don't process event during typing letters/digits into inputs without modifier keys
                !(e.target instanceof HTMLElement &&
                    ['input', 'textarea'].includes(e.target.nodeName.toLowerCase()) &&
                    (e.code.startsWith('Key') || e.code.startsWith('Digit') || e.code.startsWith('Numpad')) &&
                    !['Control', 'Meta'].some(modifier => e.getModifierState(modifier))),
            shortcuts: bindings.map(({ action, shortcut }) => ({
                shortcut,
                handler: e => {
                    e.preventDefault();
                    dispatchShortcutEvent(action, e);
                }
            }))
        });
        return () => {
            shortcutsRef.current?.reset();
            shortcutsRef.current = undefined;
        };
    }, [target]);
    useAfterInitialEffect(() => {
        const shortcutInstance = shortcutsRef.current;
        if (shortcutInstance) {
            shortcutInstance.reset();
            shortcutInstance.add(bindings.map(({ action, shortcut }) => ({
                shortcut,
                handler: e => {
                    e.preventDefault();
                    dispatchShortcutEvent(action, e);
                }
            })));
        }
    }, [JSON.stringify(bindings)]);
    return _jsx(_Fragment, { children: children });
};
export default ShortcutManager;
//# sourceMappingURL=ShortcutManager.js.map