import * as _ from 'lodash';
import { MenuRegistry } from 'monaco-editor/esm/vs/platform/actions/common/actions.js';
import { AbstractStore } from '@journeyapps-labs/reactor-mod';
import { KeybindingsRegistry } from './KeybindingsRegistry';
import { autorun } from 'mobx';
export class MonacoKeybindingStore extends AbstractStore {
    constructor(options2) {
        super({
            name: 'MONACO_KEYBINDING_STORE'
        });
        this.options2 = options2;
        this.getDefaultActions = _.memoize(async () => {
            let actionMap = new Map();
            // actions we can get from the editor
            const editorHandle = await this.options2.editorStore.createHeadlessEditorInstance();
            Array.from(editorHandle.editor._actions.values()).forEach((a) => {
                actionMap.set(a.id, a.label);
            });
            editorHandle.dispose();
            // actions we get from the menu (yeah for some reason they are separate)
            Array.from(MenuRegistry.getCommands().values()).forEach((a) => {
                actionMap.set(a.id, a.title.value);
            });
            // actions we can get from the editor
            return _.map(Array.from(actionMap.entries()), ([id, label]) => {
                const commandBinding = this.keybindingRegistry.getCommandKeybinding(id);
                return {
                    bindings: commandBinding.getDefaults(),
                    id: id,
                    label: label
                };
            });
        });
        this.actions = [];
        this.focusedEditor = null;
        this.keybindingRegistry = new KeybindingsRegistry();
        options2.editorStore.registerListener({
            gotEditor: (editor) => {
                let autorunDisposer;
                const l1 = editor.onDidFocusEditorText(() => {
                    this.focusedEditor = editor;
                });
                const l3 = editor.onDidBlurEditorText(() => {
                    autorunDisposer = this.setupFocusRestoration(editor, autorunDisposer);
                });
                const l2 = editor.onDidDispose(() => {
                    l1.dispose();
                    l2.dispose();
                    l3.dispose();
                    autorunDisposer === null || autorunDisposer === void 0 ? void 0 : autorunDisposer();
                });
            }
        });
        this.keybindingRegistry.registerListener({
            saved: () => {
                for (const editor of _.values(options2.editorStore.editors)) {
                    editor._standaloneKeybindingService.updateResolver();
                }
            }
        });
    }
    async _init() {
        this.keybindingRegistry.load();
        this.actions = await this.getDefaultActions();
    }
    /*
    If the cmd palette is opened while we have focus, we don't want to clear the focus editor, because
    we need it when using the `MonacoCommandPalletSearchEngine`. In all other cases, we want to clear
    this so that the Reactor Actions appear first
    */
    setupFocusRestoration(editor, existingDisposer) {
        const isCmdPaletteOpen = this.options2.cmdPaletteStore.show !== null;
        if (!isCmdPaletteOpen) {
            this.scheduleFocusedEditorCleanup(editor);
            return existingDisposer;
        }
        existingDisposer === null || existingDisposer === void 0 ? void 0 : existingDisposer();
        let newDisposer = null;
        newDisposer = autorun(() => {
            const isCmdPaletteClosed = this.options2.cmdPaletteStore.show === null;
            if (!isCmdPaletteClosed) {
                return;
            }
            editor.focus();
            this.focusedEditor = null;
            newDisposer === null || newDisposer === void 0 ? void 0 : newDisposer();
            newDisposer = null;
        });
        return newDisposer;
    }
    scheduleFocusedEditorCleanup(editor) {
        setTimeout(() => {
            if (this.focusedEditor !== editor) {
                return;
            }
            this.focusedEditor = null;
        }, 1000);
    }
    getActionFromID(id) {
        return _.find(this.actions, { id: id });
    }
    getContextualActions() {
        if (!this.focusedEditor) {
            return [];
        }
        return this.focusedEditor.getSupportedActions().filter((a) => a.isSupported());
    }
    unbindAction(actionID, bindings) {
        this.keybindingRegistry.getCommandKeybinding(actionID).deleteKeybinding({
            chords: bindings
        });
    }
    updateAction(operation) {
        this.keybindingRegistry.getCommandKeybinding(operation.action.id).addKeybinding({
            chords: [operation.binding, ...(operation.binding2 ? [operation.binding2] : [])]
        });
    }
}
//# sourceMappingURL=MonacoKeybindingStore.js.map