/**
 * Description: Cette class est chargée lorsque le composant 'eac-addon-site-search' est chargé dans la page
 *
 * https://developers.elementor.com/add-javascript-to-elementor-widgets/
 * 
 * @param $element. Le contenu de la section/container
 * @since 2.1.0
 */

class widgetSiteSearch extends elementorModules.frontend.handlers.Base {
    getDefaultSettings() {
        return {
            selectors: {
                formWrapper: '.eac-search_form-wrapper',
                searchIcon: '.search-icon',
                clearIcon: '.clear-icon',
                searchInput: '.eac-search_form-input',
                searchForm: '.eac-search_form',
                searchFormContainer: '.eac-search_form-container',
                searchButton: '.eac-search_button-toggle',
                postType: '.eac-search_form-post-type',
                autoComplete: '.eac-search_form-container .eac-search_form-input',
            },
        };
    }

    getDefaultElements() {
        const selectors = this.getSettings('selectors');
        const components = {
            $formWrapper: this.$element.find(selectors.formWrapper),
            isButtonHidden: this.$element.find(selectors.formWrapper).data('hide-button'),
            hasAutocomplete: this.$element.find(selectors.formWrapper).data('autocomplete'),
            $searchIcon: this.$element.find(selectors.searchIcon),
            $clearIcon: this.$element.find(selectors.clearIcon),
            $searchInput: this.$element.find(selectors.searchInput),
            $searchForm: this.$element.find(selectors.searchForm),
            $searchFormContainer: this.$element.find(selectors.searchFormContainer),
            $searchButton: this.$element.find(selectors.searchButton),
            $postType: this.$element.find(selectors.postType),
            $autoComplete: this.$element.find(selectors.autoComplete),
        };

        components.$searchIcon.css('display', 'flex');
        components.$clearIcon.css('display', 'none');
        components.$searchInput.val('');

        if (components.isButtonHidden) {
            components.$searchButton.css('display', 'none');
            components.$searchFormContainer.css('display', 'flex');
        } else {
            components.$searchIcon.css('display', 'none');
        }

        return components;
    }

    onInit() {
        super.onInit();
        const that = this.elements;

        if (this.elements.hasAutocomplete && !elementorFrontend.isEditMode()) {
            const $input = this.elements.$autoComplete;
            
            // Limiter l'entrée à 50 caractères avant d'initialiser l'autocomplete
            if ($input.val().length > 50) {
                $input.val($input.val().substring(0, 50));
                return;
            }

            $input.autocomplete({
                source: function (request, response) {
                    jQuery.ajax({
                        dataType: 'json',
                        url: eacAutocompleteSearch.ajax_url,
                        data: {
                            term: request.term,
                            action: eacAutocompleteSearch.ajax_action,
                            security: eacAutocompleteSearch.ajax_nonce,
                        },
                        success: function (data) {
                            let payload = data.data;
                            if (typeof payload === 'string') {
                                try { payload = JSON.parse(payload); } catch (e) { payload = []; }
                            }
                            // payload attendu : array de groupes [{slug,label,items:[...]}]
                            const flat = [];
                            if (Array.isArray(payload) && payload.length && payload[0].items) {
                                payload.forEach(function (group) {
                                    const gLabel = group.label || '';
                                    const gSlug = group.slug || '';
                                    (group.items || []).forEach(function (item) {
                                        flat.push(Object.assign({}, item, { groupLabel: gLabel, groupSlug: gSlug }));
                                    });
                                });
                            } else {
                                (payload || []).forEach(function (item) { flat.push(item); });
                            }
                            response(flat);
                        }
                    });
                },
                open: function () {
                    const lngContainer = jQuery(that.$searchFormContainer).width();
                    jQuery(this).data('ui-autocomplete').menu.element.css('inline-size', lngContainer);
                    const ac = jQuery(this).data('ui-autocomplete');
                    if (ac) ac._lastGroup = null;
                },
                select: function (evt, ui) {
                    const id = evt.code || evt.key || 0;
                    if ('Tab' === id && !evt.shiftKey) return false;
                    if (ui.item.link && ui.item.link !== '') {
                        window.location.href = ui.item.link;
                    }
                },
                minLength: 3,
                delay: 300,
            });

            // surcharge rendu pour insérer headers avec value:'' et éviter erreur item.value
            const ac = $input.data('ui-autocomplete') || $input.data('autocomplete');
            if (ac) {
                const _oldRenderItem = ac._renderItem;
                ac._renderItem = function (ul, item) {
                    if (item.groupLabel && this._lastGroup !== item.groupLabel) {
                        this._lastGroup = item.groupLabel;
                        const headerItem = { label: item.groupLabel, value: '' };
                        const $li = jQuery('<li class="ui-autocomplete-group" role="presentation">')
                            .attr('aria-label', headerItem.label)
                            .text(headerItem.label)
                            .appendTo(ul);
                        $li.data('ui-autocomplete-item', headerItem);
                    }
                    return _oldRenderItem.call(this, ul, item);
                };

                // empêche le focus de rester sur les headers en réorientant le menufocus
                $input.on('menufocus', function (event, ui) {
                    const $target = ui && ui.item && ui.item.element;
                    if ($target && $target.hasClass && $target.hasClass('ui-autocomplete-group')) {
                        const $next = $target.nextAll(':not(.ui-autocomplete-group):first');
                        const $prev = $target.prevAll(':not(.ui-autocomplete-group):first');
                        const $toFocus = $next.length ? $next : $prev.length ? $prev : null;
                        if ($toFocus && $toFocus.length) {
                            try { $toFocus.trigger('mouseenter'); } catch (e) { /* noop */ }
                        } else {
                            event.preventDefault();
                        }
                    }
                });
            }
        }
    }

    bindEvents() {
        this.elements.$searchButton.on('click', (evt) => { this.searchButton(evt); });
        this.elements.$searchInput.on('keyup', (evt) => { this.searchInput(evt); });
        this.elements.$clearIcon.on('keydown click', (evt) => { this.clearIcon(evt); });
    }

    searchButton(evt) {
        evt.preventDefault();

        if (this.elements.$searchFormContainer.css('display') === 'none') {
            this.elements.$clearIcon.css('display', 'none');
            this.elements.$searchButton.attr('aria-expanded', 'true');
            this.elements.$searchFormContainer.css('display', 'flex');
        } else {
            this.elements.$searchInput.val('');
            this.elements.$clearIcon.css('display', 'none');
            this.elements.$searchButton.attr('aria-expanded', 'false');
            this.elements.$searchFormContainer.css('display', 'none');
        }
    }

    searchInput(evt) {
        const $this = jQuery(evt.currentTarget);
        evt.preventDefault();

        if ($this.val().length > 50) {
            $this.val($this.val().substring(0, 50));
            return;
        }

        if ($this.is('[aria-expanded]') && $this.val().length > 2) {
            $this.attr('aria-expanded', 'true');
        } else if ($this.is('[aria-expanded]') && $this.val().length < 3) {
            $this.attr('aria-expanded', 'false');
        }

        if ($this.val() && this.elements.$clearIcon.css('display') === 'none') {
            this.elements.$searchIcon.css('display', 'none');
            this.elements.$clearIcon.css('display', 'flex');
        } else if (!$this.val()) {
            this.elements.isButtonHidden ? this.elements.$searchIcon.css('display', 'flex') : this.elements.$searchIcon.css('display', 'none');
            this.elements.$clearIcon.css('display', 'none');
        }
    }

    clearIcon(evt) {
        const id = evt.code || evt.key || 0;
        if ('keydown' === evt.type && ('Enter' !== id && 'Space' !== id)) {
            return;
        }
        evt.preventDefault();

        this.elements.$searchInput.val('');
        this.elements.isButtonHidden ? this.elements.$searchIcon.css('display', 'flex') : this.elements.$searchIcon.css('display', 'none');
        this.elements.$clearIcon.css('display', 'none');
        this.elements.$searchInput.focus();
        this.elements.$searchInput.is('[aria-expanded]') ? this.elements.$searchInput.attr('aria-expanded', 'false') : '';
    }
}

/**
 * Description: La class est créer lorsque le composant 'eac-addon-site-search' est chargé dans la page
 *
 * @param $element
 * @since 2.1.0
 */
jQuery(window).on('elementor/frontend/init', () => {
    elementorFrontend.elementsHandler.attachHandler('eac-addon-site-search', widgetSiteSearch);
});
