"use strict";
var __webpack_require__ = {};
(()=>{
    __webpack_require__.n = (module)=>{
        var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
        __webpack_require__.d(getter, {
            a: getter
        });
        return getter;
    };
})();
(()=>{
    __webpack_require__.d = (exports1, definition)=>{
        for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
            enumerable: true,
            get: definition[key]
        });
    };
})();
(()=>{
    __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
})();
(()=>{
    __webpack_require__.r = (exports1)=>{
        if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
            value: 'Module'
        });
        Object.defineProperty(exports1, '__esModule', {
            value: true
        });
    };
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
    SuggestionManager: ()=>SuggestionManager
});
const bueno_namespaceObject = require("@coveo/bueno");
const external_dompurify_namespaceObject = require("dompurify");
var external_dompurify_default = /*#__PURE__*/ __webpack_require__.n(external_dompurify_namespaceObject);
const debounce_utils_cjs_namespaceObject = require("../../../utils/debounce-utils.cjs");
const promise_utils_cjs_namespaceObject = require("../../../utils/promise-utils.cjs");
const external_suggestions_utils_cjs_namespaceObject = require("./suggestions-utils.cjs");
class SuggestionManager {
    get partialSuggestionBindings() {
        return {
            suggestedQuery: ()=>this.suggestedQuery,
            clearSuggestions: ()=>this.clearSuggestions(),
            triggerSuggestions: ()=>this.triggerSuggestions(),
            getSuggestions: ()=>this.suggestions,
            getSuggestionElements: ()=>this.allSuggestionElements
        };
    }
    get activeDescendantElement() {
        if (!this.hasActiveDescendant) return null;
        return this.leftPanel?.querySelector(`#${this.activeDescendant}`) || this.rightPanel?.querySelector(`#${this.activeDescendant}`) || null;
    }
    onSubmit() {
        this.clickOnActiveElement();
        this.clearSuggestions();
    }
    updateActiveDescendant(id = '') {
        this.activeDescendant = id;
        this.ownerSearchBoxProps.getHost().requestUpdate();
    }
    updateKeyboardActiveDescendant(id = '') {
        this.keyboardActiveDescendant = id;
    }
    clickOnActiveElement() {
        this.activeDescendantElement?.click();
        this.updateActiveDescendant();
    }
    isRightPanelInFocus() {
        if ((0, bueno_namespaceObject.isNullOrUndefined)(this.panelInFocus) || (0, bueno_namespaceObject.isNullOrUndefined)(this.rightPanel)) return false;
        return this.panelInFocus === this.rightPanel;
    }
    initializeSuggestions(bindings) {
        this.suggestions = this.suggestionEvents.map((event)=>event(bindings));
    }
    registerSuggestionsFromEvent(event, bindings) {
        event.preventDefault();
        event.stopPropagation();
        this.suggestionEvents.push(event.detail);
        this.suggestions.push(event.detail(bindings));
    }
    registerSuggestions(suggestions) {
        this.suggestions.push(suggestions);
    }
    get isDoubleList() {
        return Boolean(this.leftSuggestionElements.length && this.rightSuggestionElements.length);
    }
    focusPanel(side) {
        const panel = 'left' === side ? this.leftPanel : this.rightPanel;
        if (this.panelInFocus === panel) return;
        if (panel?.firstElementChild) {
            const panelHasActiveDescendant = this.previousActiveDescendantElement && panel.contains(this.previousActiveDescendantElement);
            const newValue = panelHasActiveDescendant ? this.previousActiveDescendantElement : panel.firstElementChild;
            this.updateDescendants(newValue.id);
        }
    }
    clearSuggestions() {
        this.clearSuggestionElements();
        this.updateActiveDescendant();
    }
    async focusNextValue() {
        if (!this.hasSuggestions || !this.nextOrFirstValue) return;
        await this.focusValue(this.nextOrFirstValue);
    }
    async focusValue(value) {
        this.updateKeyboardActiveDescendant(value.id);
        this.updateActiveDescendant(value.id);
        this.scrollActiveDescendantIntoView();
        await this.updateQueryFromSuggestion();
    }
    async onSuggestionMouseOver(item, side, id) {
        const thisPanel = 'left' === side ? this.leftPanel : this.rightPanel;
        this.updateKeyboardActiveDescendant();
        if (this.panelInFocus === thisPanel) this.updateActiveDescendant(id);
        else this.updateDescendants(id);
        if (item.query) await this.updateSuggestedQuery(item.query);
    }
    async onSuggestionClick(item, e) {
        if (item.query) {
            this.clearSuggestions();
            await this.updateOwnerSearchboxQuery(item.query);
        }
        item.onSelect?.(e);
    }
    get hasSuggestions() {
        return !!this.allSuggestionElements.length;
    }
    get allSuggestionElements() {
        return [
            ...this.leftSuggestionElements,
            ...this.rightSuggestionElements
        ];
    }
    async focusPreviousValue() {
        if (this.firstValue === this.activeDescendantElement) {
            this.updateKeyboardActiveDescendant();
            this.updateActiveDescendant();
            return;
        }
        if (!this.hasSuggestions || !this.previousOrLastValue) return;
        await this.focusValue(this.previousOrLastValue);
    }
    get hasActiveDescendant() {
        return '' !== this.activeDescendant;
    }
    async executeQuerySuggestion() {
        this.updateActiveDescendant();
        const settled = await Promise.allSettled(this.suggestions.map((suggestion)=>(0, promise_utils_cjs_namespaceObject.promiseTimeout)(suggestion.onInput ? suggestion.onInput() : Promise.resolve(), this.ownerSearchBoxProps.getSuggestionTimeout())));
        const fulfilledSuggestions = [];
        settled.forEach((prom, j)=>{
            if ('fulfilled' === prom.status) fulfilledSuggestions.push(this.suggestions[j]);
            else this.ownerSearchBoxProps.getLogger().warn('Some query suggestions are not being shown because the promise timed out.');
        });
        const splitSuggestions = (side, isDefault = false)=>fulfilledSuggestions.filter((suggestion)=>suggestion.panel === side || !suggestion.panel && isDefault).sort(this.sortSuggestions);
        this.leftSuggestions = splitSuggestions('left', true);
        this.leftSuggestionElements = this.getAndFilterLeftSuggestionElements();
        this.rightSuggestions = splitSuggestions('right');
        this.rightSuggestionElements = this.getSuggestionElements(this.rightSuggestions);
        const defaultSuggestedQuery = this.allSuggestionElements.find(external_suggestions_utils_cjs_namespaceObject.elementHasQuery)?.query || '';
        await this.updateSuggestedQuery(defaultSuggestedQuery);
    }
    get lastValue() {
        return this.panelInFocus?.lastElementChild;
    }
    get previousOrLastValue() {
        if (!this.hasActiveDescendant) return this.lastValue?.firstChild;
        const parentOfActiveDescendant = this.activeDescendantElement?.parentElement;
        return parentOfActiveDescendant?.previousElementSibling?.firstChild || this.firstValue?.firstChild;
    }
    sortSuggestions(a, b) {
        return a.position - b.position;
    }
    get nextOrFirstValue() {
        if (!this.hasActiveDescendant) return this.firstValue?.firstChild;
        const parentOfActiveDescendant = this.activeDescendantElement?.parentElement;
        return parentOfActiveDescendant?.nextElementSibling?.firstChild || this.firstValue?.firstChild;
    }
    get firstValue() {
        return this.panelInFocus?.firstElementChild;
    }
    get panelInFocus() {
        if (this.leftPanel?.contains(this.activeDescendantElement)) return this.leftPanel;
        if (this.rightPanel?.contains(this.activeDescendantElement)) return this.rightPanel;
        return this.leftPanel || this.rightPanel;
    }
    scrollActiveDescendantIntoView() {
        this.activeDescendantElement?.scrollIntoView({
            block: 'nearest'
        });
    }
    async updateQueryFromSuggestion() {
        const suggestedQuery = this.activeDescendantElement?.getAttribute(this.queryDataAttribute);
        await this.updateOwnerSearchboxQuery(suggestedQuery || '');
    }
    async updateOwnerSearchboxQuery(query) {
        if (query && this.ownerSearchBoxProps.getSearchBoxValue() !== query) {
            this.ownerSearchBoxProps.updateQuery(query);
            await this.updateSuggestedQuery(query);
        }
    }
    async updateSuggestedQuery(suggestedQuery) {
        await Promise.allSettled(this.suggestions.map((suggestion)=>(0, promise_utils_cjs_namespaceObject.promiseTimeout)(suggestion.onSuggestedQueryChange ? suggestion.onSuggestedQueryChange(suggestedQuery) : Promise.resolve(), this.ownerSearchBoxProps.getSuggestionTimeout())));
        this.suggestedQuery = suggestedQuery;
        this.updateSuggestionElements(suggestedQuery);
        this.ownerSearchBoxProps.getHost().requestUpdate();
    }
    updateSuggestionElements(query) {
        if (!this.isPanelInFocus(this.leftPanel, query)) this.leftSuggestionElements = this.getAndFilterLeftSuggestionElements();
        if (!this.isPanelInFocus(this.rightPanel, query)) this.rightSuggestionElements = this.getSuggestionElements(this.rightSuggestions);
    }
    forceUpdate() {
        this.updateSuggestionElements(this.suggestedQuery);
        this.ownerSearchBoxProps.getHost().requestUpdate();
    }
    isPanelInFocus(panel, query) {
        if (!this.activeDescendantElement) return false;
        if (query) {
            const escaped = external_dompurify_default().sanitize(query);
            return !!panel?.querySelector(`[${this.queryDataAttribute}="${CSS.escape(escaped)}"]`);
        }
        return this.activeDescendantElement?.closest('ul') === panel;
    }
    getAndFilterLeftSuggestionElements() {
        const suggestionElements = this.getSuggestionElements(this.leftSuggestions);
        const filterOnDuplicate = new Set();
        const out = suggestionElements.filter((suggestionElement)=>{
            if ((0, bueno_namespaceObject.isNullOrUndefined)(suggestionElement.query)) return true;
            if (filterOnDuplicate.has(suggestionElement.query)) return false;
            filterOnDuplicate.add(suggestionElement.query);
            return true;
        });
        return out;
    }
    getSuggestionElements(suggestions) {
        const elements = suggestions.flatMap((suggestion)=>suggestion.renderItems());
        const max = this.ownerSearchBoxProps.getNumberOfSuggestionsToDisplay() + elements.filter(external_suggestions_utils_cjs_namespaceObject.elementHasNoQuery).length;
        return elements.slice(0, max);
    }
    updateDescendants(activeDescendant = '') {
        const newPrevDescendantElement = this.activeDescendantElement;
        this.previousActiveDescendantElement = newPrevDescendantElement;
        this.updateActiveDescendant(activeDescendant);
    }
    clearSuggestionElements() {
        this.leftSuggestionElements = [];
        this.rightSuggestionElements = [];
    }
    constructor(ownerSearchBoxProps){
        this.ownerSearchBoxProps = ownerSearchBoxProps;
        this.suggestions = [];
        this.leftSuggestionElements = [];
        this.rightSuggestionElements = [];
        this.leftPanel = void 0;
        this.rightPanel = void 0;
        this.activeDescendant = '';
        this.suggestedQuery = '';
        this.keyboardActiveDescendant = '';
        this.queryDataAttribute = 'data-query';
        this.suggestionEvents = [];
        this.previousActiveDescendantElement = null;
        this.leftSuggestions = [];
        this.rightSuggestions = [];
        this.triggerSuggestions = (0, debounce_utils_cjs_namespaceObject.debounce)(()=>this.executeQuerySuggestion(), this.ownerSearchBoxProps.getSuggestionDelay());
    }
}
exports.SuggestionManager = __webpack_exports__.SuggestionManager;
for(var __rspack_i in __webpack_exports__)if (-1 === [
    "SuggestionManager"
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
Object.defineProperty(exports, '__esModule', {
    value: true
});
