(function ($) {
    "use strict";

    var PENCI = window.PENCI || {};

    PENCI.ajaxsearch = function () {

        // ── Helpers ───────────────────────────────────────────────────────────────

        var escapeHtml = function (str) {
            return String(str)
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#039;');
        };

        var debounce = function (fn, delay) {
            var timer;
            return function () {
                var ctx  = this;
                var args = arguments;
                clearTimeout(timer);
                timer = setTimeout(function () {
                    fn.apply(ctx, args);
                }, delay);
            };
        };

        var $body          = $('body');
        var defaultNumber  = parseInt(penci_ajsr.maxitems, 10) || 5;
        var resolvedNumber = defaultNumber;

        if ($body.find('.header-search-style-showup').length)   { resolvedNumber = 3; }
        if ($body.find('.header-search-style-default').length)  { resolvedNumber = 8; }
        if ($body.find('.header-search-style-overlay').length)  { resolvedNumber = 6; }

        // Theme-level override wins when both citems AND maxitems are set.
        if (penci_ajsr.citems && penci_ajsr.maxitems) {
            resolvedNumber = parseInt(penci_ajsr.maxitems, 10);
        }

        // ── Per-form setup ────────────────────────────────────────────────────────
        $('form.penci-ajax-search').each(function () {

            var $form      = $(this);
            var $wrapper   = $form.parent();
            var $results   = $wrapper.find('.penci-dropdown-results > .penci-search-results-wrapper');
            var $container = $wrapper.find('.penci-dropdown-results');

            // Per-form overrides (data attrs set by PHP)
            var number    = $form.data('count')     ? parseInt($form.data('count'), 10)     : resolvedNumber;
            var thumbnail = $form.data('thumbnail') ? parseInt($form.data('thumbnail'), 10) : parseInt(penci_ajsr.thumbnail, 10);
            var date      = parseInt(penci_ajsr.date, 10);

            // In-flight XHR handle — lets us abort stale requests.
            var activeXhr = null;

            // ── Result rendering ──────────────────────────────────────────────────

            var renderSuggestions = function (data) {

                var $list = $('<div class="autocomplete-suggestions"></div>');

                $.each(data.suggestions, function (index, suggestion) {
                    if (suggestion.no_found) {
                        $list.append(
                            $('<span class="no-found-msg"></span>').text(suggestion.value)
                        );
                        return;
                    }

                    var $item = $('<div class="autocomplete-suggestion"></div>')
                        .attr('data-index', index);

                    if (thumbnail && suggestion.thumbnail) {
                        // thumbnail is server-rendered HTML — PHP already escapes it.
                        $item.append($('<div class="suggestion-thumb"></div>').html(suggestion.thumbnail));
                    }

                    if (suggestion.value) {
                        var $link = $('<a></a>')
                            .attr('href', escapeHtml(suggestion.permalink))
                            .attr('title', escapeHtml(suggestion.title))
                            .text(suggestion.value);  // .text() is XSS-safe

                        var $content = $('<div class="suggestion-content reset-last-child"></div>')
                            .append($('<h4 class="penci-post-title"></h4>').append($link));

                        if (date && suggestion.date) {
                            $content.append(
                                $('<span class="post-date"></span>').text(suggestion.date)
                            );
                        }

                        $item.append($content);
                    }

                    $list.append($item);
                });

                $results.empty().append($list);

                // "View all" link
                $results.find('.view-all-results').remove();
                if ($list.find('.autocomplete-suggestion').length > 2 && penci_ajsr.allresults) {
                    var $viewAll = $('<div class="view-all-results"><span></span></div>');
                    $viewAll.find('span').append(
                        $('<a></a>')
                            .attr('href', data.allsearch)  // already esc_url()'d in PHP
                            .text(penci_ajsr.allresults)
                    );
                    $results.append($viewAll);
                }

                var hasItems = $list.find('.autocomplete-suggestion').length > 1;
                $form.closest('.penci-search-form').toggleClass('has-search-items', hasItems);
                $container.addClass('penci-opened');
            };

            // ── Lazy-load init (extracted to avoid repeating the config object) ──
            var initLazyLoad = function () {
                // Guard: LazyLoad may not be present on every install.
                if (typeof LazyLoad === 'undefined') { return; }
                new LazyLoad({
                    elements_selector : '.penci-lazy',
                    data_bg           : 'bgset',
                    class_loading     : 'lazyloading',
                    class_entered     : 'lazyloaded',
                    class_loaded      : 'pcloaded',
                    unobserve_entered : true
                });
            };

            // ── Input handler ─────────────────────────────────────────────────────
            $form.find('[type="text"]').on(
                'focus keyup',
                debounce(function () {
                    var $input = $(this);
                    var query  = $.trim($input.val());
                    var minChar = parseInt(penci_ajsr.minchar, 10) || 2;

                    if (query.length < minChar) {
                        // Hide stale results when the user clears the field.
                        if (query.length === 0) {
                            $results.empty();
                            $container.removeClass('penci-opened');
                            $form.closest('.penci-search-form').removeClass('has-search-items pcajx-search-open');
                        }
                        return;
                    }

                    if (activeXhr) {
                        activeXhr.abort();
                    }

                    var requestData = {
                        action : 'penci_ajax_search',
                        number : number,
                        nonce  : penci_ajsr.nonce,
                        query  : query
                    };

                    activeXhr = $.ajax({
                        type     : 'GET',
                        dataType : 'json', // FIX: was 'html' then manually JSON.parse()'d — error-prone
                        url      : penci_ajsr.ajaxUrl,
                        data     : requestData,

                        beforeSend: function () {
                            $form.addClass('search-loading');
                            $form.closest('.show-search').addClass('pcajx-search-loading');
                            $form.closest('.penci-search-form').addClass('pcajx-search-open');
                        },

                        success: function (response) {

                            var data = (response && response.success === true && response.data)
                                ? response.data
                                : response;

                            if (!data || !$.isArray(data.suggestions)) {
                                console.warn('[penci-ajaxsearch] Unexpected response shape:', response);
                                return;
                            }

                            renderSuggestions(data);
                        },

                        error: function (xhr, status) {
                            // Silently ignore user-triggered aborts; log real errors.
                            if (status === 'abort') { return; }
                            console.warn('[penci-ajaxsearch] Request failed:', status);
                            $results.empty();
                            $container.removeClass('penci-opened');
                        },

                        complete: function () {
                            activeXhr = null;
                            $form.removeClass('search-loading');
                            $form.closest('.show-search').removeClass('pcajx-search-loading');
                            $(document).trigger('penci-images-loaded');
                            initLazyLoad();
                        }
                    });
                }, 250)
            );

            // ── "View all" keyboard shortcut ──────────────────────────────────────
            $results.on('click', '.view-all-results', function () {
                $form.trigger('submit');
            });
        });

        // ── Single document-level close handler (replaces per-form binding) ───────
        $(document).on('click.penci-ajaxsearch', function (e) {
            var $t = $(e.target);
            var insideSearch = $t.closest('.penci-search-form, .penci-search-full-screen').length > 0;

            if (!insideSearch) {
                $('.penci-dropdown-results').removeClass('penci-opened');
                $('.penci-search-form').removeClass('has-search-items pcajx-search-open');
            }
        });

        $(document).on(
            'click.penci-ajaxsearch',
            '.penci-dropdown-results > .penci-search-results-wrapper',
            function (e) { e.stopPropagation(); }
        );
    };

    // ── Boot ──────────────────────────────────────────────────────────────────────
    $(document).ready(function () {
        PENCI.ajaxsearch();
    });

})(jQuery);