import { SearchQuery, closeSearchPanel, findNext, findPrevious, getSearchQuery, search, searchKeymap, searchPanelOpen, setSearchQuery, } from '@codemirror/search';
import { ViewPlugin, keymap, } from '@codemirror/view';
import { debounce } from "../../../lodash.js";
import { ReactRendererFacet } from "../react-facet.js";
import { renderSearchPopup } from "./view/SearchPopup.js";
const INPUT_DELAY = 200;
export const SearchPanelPlugin = (params) => ViewPlugin.fromClass(class {
    view;
    params;
    anchor;
    renderer;
    searchConfig = {
        search: '',
        caseSensitive: false,
        wholeWord: false,
    };
    receiver;
    setViewSearchWithDelay;
    constructor(view) {
        this.view = view;
        this.anchor = null;
        this.renderer = null;
        this.params = params;
        this.receiver = params.receiver;
        this.handleClose = this.handleClose.bind(this);
        this.handleChange = this.handleChange.bind(this);
        this.handleSearchNext = this.handleSearchNext.bind(this);
        this.handleSearchPrev = this.handleSearchPrev.bind(this);
        this.handleSearchConfigChange = this.handleSearchConfigChange.bind(this);
        this.handleEditorModeChange = this.handleEditorModeChange.bind(this);
        this.setViewSearchWithDelay = debounce(this.setViewSearch, this.params.inputDelay ?? INPUT_DELAY);
        this.receiver?.on('change-editor-mode', this.handleEditorModeChange);
    }
    update(update) {
        const isPanelOpen = searchPanelOpen(update.state);
        if (isPanelOpen && !this.renderer) {
            const initial = getSearchQuery(update.state);
            this.anchor = document.querySelector(this.params.anchorSelector);
            this.renderer = this.view.state
                .facet(ReactRendererFacet)
                .createItem('cm-search', () => renderSearchPopup({
                initial,
                open: true,
                anchor: this.anchor,
                onChange: this.handleChange,
                onClose: this.handleClose,
                onSearchNext: this.handleSearchNext,
                onSearchPrev: this.handleSearchPrev,
                onConfigChange: this.handleSearchConfigChange,
            }));
        }
        else if (!isPanelOpen && this.renderer) {
            this.renderer?.remove();
            this.renderer = null;
        }
    }
    destroy() {
        this.renderer?.remove();
        this.renderer = null;
        this.receiver?.off('change-editor-mode', this.handleEditorModeChange);
    }
    setViewSearch(config) {
        this.searchConfig = {
            ...this.searchConfig,
            ...config,
        };
        const searchQuery = new SearchQuery({
            ...this.searchConfig,
        });
        this.view.dispatch({ effects: setSearchQuery.of(searchQuery) });
    }
    handleEditorModeChange({ mode }) {
        if (mode === 'wysiwyg') {
            closeSearchPanel(this.view);
        }
    }
    handleChange(search) {
        this.setViewSearchWithDelay({ search });
    }
    handleClose() {
        this.setViewSearch({ search: '' });
        closeSearchPanel(this.view);
    }
    handleSearchNext() {
        findNext(this.view);
    }
    handleSearchPrev() {
        findPrevious(this.view);
    }
    handleSearchConfigChange(config) {
        this.setViewSearch(config);
    }
}, {
    provide: () => [
        keymap.of(searchKeymap),
        search({
            createPanel: () => ({
                // Create an empty search panel
                dom: document.createElement('div'),
            }),
        }),
    ],
});
//# sourceMappingURL=plugin.js.map
