(function() {
    'use strict';

    function pfInit() {
        document.querySelectorAll('[data-askagento-ai-text-search-root]').forEach(function(root) {
            bindAiTextSearch(root);
        });

        document.querySelectorAll('[data-askagento-ai-image-search-root]').forEach(function(root) {
            bindAiImageSearch(root);
        });

        document.querySelectorAll('.askagento-filter').forEach(function(formEl) {
            var cfg = parsePfConfig(formEl);
            if (!cfg) {
                return;
            }
            initProductFilter(formEl, cfg);
        });
    }

    /**
     * Per-form AJAX settings (avoids binding the first .askagento-filter while askagentoFront matches another shortcode).
     */
    function parsePfConfig(formEl) {
        var raw = formEl.getAttribute('data-askagento-config');
        if (raw) {
            try {
                return JSON.parse(raw);
            } catch (e) {
                return null;
            }
        }
        if (typeof askagentoFront !== 'undefined') {
            return askagentoFront;
        }
        return null;
    }

    function resolveResultsContainer(formEl, cfg) {
        if (cfg.filterRegionId) {
            var byId = document.getElementById(cfg.filterRegionId);
            if (byId) {
                return byId;
            }
        }
        var sib = formEl.nextElementSibling;
        if (sib && sib.classList && sib.classList.contains('askagento-filter-products-region')) {
            return sib;
        }
        if (cfg.selector) {
            return document.querySelector(cfg.selector);
        }
        return null;
    }

    function initProductFilter(formEl, cfg) {
        var debounceTimer = null;
        var resultsEl = resolveResultsContainer(formEl, cfg);

        // Connected [product_filter_search]: the inline search box narrows this
        // filter's grid instead of rendering its own tile list.
        var connectedSearch = formEl.querySelector('.askagento-ai-text-search[data-askagento-connected="1"]');

        function getSearchQuery() {
            if (!connectedSearch) return '';
            var inp = connectedSearch.querySelector('.askagento-ai-text-search-input');
            var v = inp ? (inp.value || '').trim() : '';
            return v.length >= 2 ? v : '';
        }

        function getFormData() {
            var data = {};

            formEl.querySelectorAll('input[type="checkbox"]:checked').forEach(function(input) {
                var name = input.name.replace('[]', '');
                if (!data[name]) {
                    data[name] = [];
                }
                data[name].push(input.value);
            });

            formEl.querySelectorAll('input[type="radio"]:checked').forEach(function(input) {
                if (input.value) {
                    data[input.name] = input.value;
                }
            });

            formEl.querySelectorAll('select').forEach(function(select) {
                if (select.value) {
                    data[select.name] = select.value;
                }
            });

            formEl.querySelectorAll('.askagento-range-value').forEach(function(input) {
                var wrap = input.closest('.askagento-range-wrap');
                if (wrap) {
                    var lo = wrap.querySelector('.askagento-range-min');
                    var hi = wrap.querySelector('.askagento-range-max');
                    var dmin = wrap.getAttribute('data-min');
                    var dmax = wrap.getAttribute('data-max');
                    if (
                        lo && hi && dmin !== null && dmax !== null &&
                        String(lo.value) === String(dmin) && String(hi.value) === String(dmax)
                    ) {
                        return;
                    }
                }
                if (input.value && input.value !== '-') {
                    data[input.name] = input.value;
                }
            });

            return data;
        }

        function updateUrl(data) {
            var url = new URL(window.location.href);

            Array.from(url.searchParams.keys()).forEach(function(key) {
                if (key.indexOf('_askagento_t_') === 0 || key.indexOf('_askagento_m_') === 0 || key.indexOf('_askagento_n_') === 0) {
                    url.searchParams.delete(key);
                }
            });

            Object.keys(data).forEach(function(key) {
                var val = data[key];
                if (Array.isArray(val)) {
                    val.forEach(function(v) {
                        url.searchParams.append(key + '[]', v);
                    });
                } else {
                    url.searchParams.set(key, val);
                }
            });

            return url.toString();
        }

        function postFilteredProductsMarkup(data) {
            var fd = new FormData();
            fd.append('action', 'askagento_get_filtered_products');
            fd.append('nonce', cfg.nonce);
            fd.append('filter_id', String(cfg.filterId));

            Object.keys(data).forEach(function(key) {
                var val = data[key];
                if (Array.isArray(val)) {
                    val.forEach(function(v) {
                        fd.append('current[' + key + '][]', v);
                    });
                } else {
                    fd.append('current[' + key + ']', val);
                }
            });

            var q = getSearchQuery();
            if (q) {
                fd.append('q', q);
            }

            return fetch(cfg.ajaxUrl, {
                method: 'POST',
                body: fd,
                credentials: 'same-origin'
            }).then(function(response) {
                return response.json();
            });
        }

        function updateCounts(data) {
            var formData = new FormData();
            formData.append('action', 'askagento_get_counts');
            formData.append('nonce', cfg.nonce);
            formData.append('filter_id', String(cfg.filterId));

            Object.keys(data).forEach(function(key) {
                var val = data[key];
                if (Array.isArray(val)) {
                    val.forEach(function(v) {
                        formData.append('current[' + key + '][]', v);
                    });
                } else {
                    formData.append('current[' + key + ']', val);
                }
            });

            fetch(cfg.ajaxUrl, {
                method: 'POST',
                body: formData,
                credentials: 'same-origin'
            })
                .then(function(response) {
                    return response.json();
                })
                .then(function(r) {
                    if (!r.success) {
                        return;
                    }

                    var counts = r.data;

                    Object.keys(counts).forEach(function(fieldName) {
                        var fieldCounts = counts[fieldName];
                        var field = formEl.querySelector('.askagento-field[data-field="' + fieldName + '"]');
                        if (!field) {
                            return;
                        }

                        if (typeof fieldCounts === 'object' && fieldCounts.min !== undefined) {
                            var hint = field.querySelector('.askagento-range-available');
                            if (hint) {
                                hint.textContent = 'Available: ' + fieldCounts.min + ' — ' + fieldCounts.max;
                            }
                            return;
                        }

                        Object.keys(fieldCounts).forEach(function(value) {
                            var count = fieldCounts[value];
                            var opt = field.querySelector('.askagento-option[data-value="' + value + '"]');

                            if (opt) {
                                var countEl = opt.querySelector('.askagento-count');
                                if (countEl) {
                                    countEl.textContent = '(' + count + ')';
                                }

                                var input = opt.querySelector('input');
                                if (input) {
                                    if (count === 0 && !input.checked) {
                                        opt.classList.add('askagento-empty');
                                        input.disabled = true;
                                    } else {
                                        opt.classList.remove('askagento-empty');
                                        input.disabled = false;
                                    }
                                }
                            }

                            var option = field.querySelector('select option[value="' + value + '"]');
                            if (option) {
                                // Trim first: the server renders the option text on its own
                                // indented line, so textContent has surrounding whitespace. Without
                                // the trim the trailing-count regex fails to match and the live
                                // count gets appended a second time ("Amber (1) (1)").
                                var label = option.textContent.trim().replace(/\s*\(\d+\)\s*$/, '');
                                option.textContent = label + ' (' + count + ')';
                                option.disabled = count === 0 && !option.selected;
                            }
                        });
                    });
                });
        }

        function cleanForm() {
            formEl.querySelectorAll('input, select').forEach(function(el) {
                if (!el.value || el.value === '-') {
                    el.disabled = true;
                }
            });

            formEl.querySelectorAll('input[type="checkbox"]:not(:checked)').forEach(function(el) {
                el.disabled = true;
            });

            formEl.querySelectorAll('input[type="radio"]:not(:checked)').forEach(function(el) {
                el.disabled = true;
            });
        }

        function doFilter() {
            var data = getFormData();
            var url = updateUrl(data);
            history.pushState(null, '', url);

            formEl.classList.add('askagento-loading');
            updateCounts(data);

            if (!cfg.ajax) {
                formEl.classList.remove('askagento-loading');
                return;
            }

            postFilteredProductsMarkup(data)
                .then(function(resp) {
                    if (!resp || !resp.success || !resp.data) {
                        return;
                    }
                    var html = resp.data.html;
                    var totalHtml = resp.data.total_html;

                    if (resultsEl && typeof html === 'string') {
                        resultsEl.innerHTML = html;
                    }

                    var currentTotal = formEl.querySelector('.askagento-total');
                    if (currentTotal && typeof totalHtml === 'string' && totalHtml !== '') {
                        currentTotal.innerHTML = totalHtml;
                    }
                })
                .finally(function() {
                    formEl.classList.remove('askagento-loading');
                });
        }

        function debounceSubmit() {
            clearTimeout(debounceTimer);
            debounceTimer = setTimeout(doFilter, 300);
        }

        function bindEvents() {
            formEl.querySelectorAll('input[type="checkbox"], input[type="radio"]').forEach(function(input) {
                input.addEventListener('change', function() {
                    if (cfg.ajax) {
                        debounceSubmit();
                    } else {
                        formEl.submit();
                    }
                });
            });

            formEl.querySelectorAll('select').forEach(function(select) {
                select.addEventListener('change', function() {
                    if (cfg.ajax) {
                        debounceSubmit();
                    } else {
                        formEl.submit();
                    }
                });
            });

            formEl.querySelectorAll('.askagento-range-min, .askagento-range-max').forEach(function(input) {
                input.addEventListener('change', function() {
                    updateRangeValue(this.closest('.askagento-range-wrap'));
                    if (cfg.ajax) {
                        debounceSubmit();
                    }
                });
            });

            formEl.addEventListener('submit', function(e) {
                if (cfg.ajax) {
                    e.preventDefault();
                    doFilter();
                } else {
                    cleanForm();
                }
            });

            formEl.querySelectorAll('.askagento-apply-filters-btn').forEach(function(btn) {
                btn.addEventListener('click', function() {
                    clearTimeout(debounceTimer);
                    if (cfg.ajax) {
                        doFilter();
                    }
                });
            });
        }

        function bindConnectedSearch() {
            var sInput = connectedSearch.querySelector('.askagento-ai-text-search-input');
            var sBtn = connectedSearch.querySelector('.askagento-ai-text-search-submit');
            var sLive = connectedSearch.getAttribute('data-live-enabled') !== '0';
            var sDebounce = parseInt(connectedSearch.getAttribute('data-live-debounce-ms'), 10);
            if (!sDebounce || sDebounce < 1) {
                sDebounce = 600;
            }
            var sTimer = null;

            function runNow() {
                if (sTimer) { clearTimeout(sTimer); sTimer = null; }
                clearTimeout(debounceTimer);
                if (cfg.ajax) {
                    doFilter();
                } else {
                    formEl.submit();
                }
            }

            if (sInput) {
                sInput.addEventListener('input', function() {
                    if (!sLive || !cfg.ajax) {
                        return;
                    }
                    if (sTimer) clearTimeout(sTimer);
                    sTimer = setTimeout(function() {
                        sTimer = null;
                        doFilter();
                    }, sDebounce);
                });
                sInput.addEventListener('keydown', function(e) {
                    if (e.key === 'Enter') {
                        e.preventDefault();
                        runNow();
                    }
                });
            }

            if (sBtn) {
                sBtn.addEventListener('click', function() {
                    runNow();
                });
            }
        }

        bindEvents();
        formEl.querySelectorAll('.askagento-range-wrap').forEach(function(wrap) {
            updateRangeValue(wrap);
        });

        if (connectedSearch) {
            bindConnectedSearch();
        } else {
            bindAiTextSearch(formEl);
        }
    }

    function updateRangeValue(wrap) {
        var min = wrap.querySelector('.askagento-range-min').value;
        var max = wrap.querySelector('.askagento-range-max').value;
        wrap.querySelector('.askagento-range-value').value = min + '-' + max;
    }

    // Guard against the script being loaded with defer/async (e.g. by a
    // performance plugin) after DOMContentLoaded has already fired.
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', pfInit);
    } else {
        pfInit();
    }

    function getAiTextSearchAjaxUrl() {
        if (typeof askagentoFront !== 'undefined' && askagentoFront.ajaxUrl) {
            return askagentoFront.ajaxUrl;
        }

        if (typeof askagentoAiTextSearchFront !== 'undefined' && askagentoAiTextSearchFront.ajaxUrl) {
            return askagentoAiTextSearchFront.ajaxUrl;
        }

        return '';
    }

    function getAiTextSearchNonce() {
        if (
            typeof askagentoFront !== 'undefined'
            && askagentoFront.aiTextSearch
            && askagentoFront.aiTextSearch.nonce
        ) {
            return askagentoFront.aiTextSearch.nonce;
        }

        if (typeof askagentoAiTextSearchFront !== 'undefined' && askagentoAiTextSearchFront.nonce) {
            return askagentoAiTextSearchFront.nonce;
        }

        return '';
    }

    function bindAiTextSearch(scope) {
        var box = scope.querySelector('.askagento-ai-text-search');

        if (!box) {
            return;
        }

        // Prefer credentials embedded directly in the HTML (data attributes) so
        // the widget works even when the global askagentoAiTextSearchFront variable is
        // absent (e.g. deferred scripts, page-builder late injection, HTML cache).
        var ajaxUrl  = box.getAttribute('data-ajax-url')  || getAiTextSearchAjaxUrl();
        var nonceVal = box.getAttribute('data-nonce')      || getAiTextSearchNonce();

        if (!ajaxUrl || !nonceVal) {
            return;
        }

        var input = box.querySelector('.askagento-ai-text-search-input');
        var btn = box.querySelector('.askagento-ai-text-search-submit');
        var statusEl = box.querySelector('.askagento-ai-text-search-status');
        var list = box.querySelector('.askagento-ai-text-search-results');

        var liveEnabled = box.getAttribute('data-live-enabled') !== '0';
        var liveDebounceMs = parseInt(box.getAttribute('data-live-debounce-ms'), 10);
        var liveCacheTtlMs = parseInt(box.getAttribute('data-live-cache-ms'), 10);

        if (!liveDebounceMs || liveDebounceMs < 1) {
            liveDebounceMs = 900;
        }

        if (liveCacheTtlMs !== 0 && (!liveCacheTtlMs || liveCacheTtlMs < 1000)) {
            liveCacheTtlMs = 300000;
        }

        var liveTimer = null;
        var pendingReqId = 0;
        var memCache = Object.create(null);

        function msg(attr, fallback) {
            return box.getAttribute(attr) || fallback;
        }

        function cacheKey(normalizedQuery) {
            return normalizedQuery.toLowerCase().trim();
        }

        function readMemCache(normalizedQuery) {
            var k = cacheKey(normalizedQuery);
            var e = memCache[k];

            if (!e || !liveCacheTtlMs) {
                return null;
            }

            if (Date.now() - e.ts > liveCacheTtlMs) {
                delete memCache[k];
                return null;
            }

            return e.results;
        }

        function writeMemCache(normalizedQuery, results) {
            if (!liveCacheTtlMs) {
                return;
            }

            memCache[cacheKey(normalizedQuery)] = {
                ts: Date.now(),
                results: results
            };
        }

        function setLoading(on) {
            box.classList.toggle('askagento-ai-text-search-loading', on);
            if (btn) btn.disabled = on;
        }

        function renderResults(rows, statusMode) {
            if (!list) return;

            list.innerHTML = '';
            list.classList.toggle('askagento-ai-text-search-results--empty', !rows || !rows.length);

            if (!rows || !rows.length) {
                if (statusMode === 'short') {
                    if (statusEl) statusEl.textContent = msg('data-msg-short', '');
                } else if (statusMode === 'preserve') {
                    /* caller sets status */
                } else if (statusMode === 'clear') {
                    if (statusEl) statusEl.textContent = '';
                } else {
                    if (statusEl) statusEl.textContent = msg('data-msg-empty', '');
                }

                return;
            }

            if (statusEl) statusEl.textContent = '';

            rows.forEach(function(row) {
                var li = document.createElement('li');
                li.className = 'askagento-ai-text-tile';
                li.setAttribute('role', 'listitem');

                var a = document.createElement('a');
                a.href = row.permalink || '#';
                a.className = 'askagento-ai-text-tile-link';

                var imgWrap = document.createElement('div');
                imgWrap.className = 'askagento-ai-text-tile-media';

                if (row.image_url) {
                    var img = document.createElement('img');
                    img.src = row.image_url;
                    img.alt = '';
                    img.loading = 'lazy';
                    img.decoding = 'async';
                    imgWrap.appendChild(img);
                } else {
                    imgWrap.classList.add('askagento-ai-text-tile-media--placeholder');
                }

                var body = document.createElement('div');
                body.className = 'askagento-ai-text-tile-body';

                var title = document.createElement('div');
                title.className = 'askagento-ai-text-tile-title';
                title.textContent = row.title || '';

                body.appendChild(title);

                if (row.price_html) {
                    var priceEl = document.createElement('div');
                    priceEl.className = 'askagento-ai-text-tile-price woocommerce';
                    priceEl.innerHTML = row.price_html;
                    body.appendChild(priceEl);
                }

                a.appendChild(imgWrap);
                a.appendChild(body);
                li.appendChild(a);
                list.appendChild(li);
            });
        }

        function runFetch(q, opts) {
            opts = opts || {};

            if (liveTimer) {
                clearTimeout(liveTimer);
                liveTimer = null;
            }

            if (q.length < 2) {
                if (statusEl) statusEl.textContent = msg('data-msg-short', '');
                renderResults([], 'short');
                return;
            }

            var memo = readMemCache(q);

            if (memo) {
                renderResults(memo);
                return;
            }

            var rid = ++pendingReqId;

            if (!opts.keepTilesUntilResponse) {
                renderResults([], 'clear');
            }

            if (statusEl) statusEl.textContent = msg('data-msg-working', '');

            setLoading(true);

            var fd = new FormData();
            fd.append('action', 'askagento_ai_text_search');
            fd.append('nonce', nonceVal);
            fd.append('q', q);

            fetch(ajaxUrl, { method: 'POST', body: fd })
                .then(function(response) {
                    return response.json();
                })
                .then(function(data) {
                    if (rid !== pendingReqId) {
                        return;
                    }

                    if (!data || !data.success) {
                        var errMsg = msg('data-msg-error', '');
                        if (data && data.data && data.data.message) {
                            errMsg = data.data.message;
                        }
                        renderResults([], 'preserve');
                        if (statusEl) statusEl.textContent = errMsg;
                        return;
                    }

                    var rowsSuccess = data.data && data.data.results ? data.data.results : [];

                    renderResults(rowsSuccess);
                    writeMemCache(q, rowsSuccess);
                })
                .catch(function() {
                    if (rid !== pendingReqId) {
                        return;
                    }

                    renderResults([], 'preserve');
                    if (statusEl) statusEl.textContent = msg('data-msg-error', '');
                })
                .finally(function() {
                    if (rid === pendingReqId) {
                        setLoading(false);
                    }
                });
        }

        function scheduleLiveSearch() {
            if (!input) return;

            if (liveTimer) clearTimeout(liveTimer);

            liveTimer = setTimeout(function() {
                liveTimer = null;
                runFetch((input.value || '').trim(), { keepTilesUntilResponse: true });
            }, liveDebounceMs);
        }

        function requestImmediate() {
            if (liveTimer) {
                clearTimeout(liveTimer);
                liveTimer = null;
            }
            runFetch((input && input.value || '').trim(), { keepTilesUntilResponse: false });
        }

        if (btn) {
            btn.addEventListener('click', function() {
                requestImmediate();
            });
        }

        if (input) {
            input.addEventListener('input', function() {
                if (!liveEnabled) {
                    return;
                }

                var q = (input.value || '').trim();

                if (q.length < 2) {
                    if (liveTimer) clearTimeout(liveTimer);
                    pendingReqId++;
                    setLoading(false);
                    if (statusEl) statusEl.textContent = msg('data-msg-short', '');
                    renderResults([], 'short');
                    return;
                }

                scheduleLiveSearch();
            });

            input.addEventListener('keydown', function(e) {
                if (e.key !== 'Enter') return;
                e.preventDefault();
                requestImmediate();
            });
        }
    }

    /**
     * Cover+center-crop to a square, then JPEG (matches API ImageOps.fit to SEARCH_QUERY_IMAGE_SIZE).
     *
     * @returns {Promise<string>}
     */
    function jpegDataUrlFromFileForPf(file, squareSide, quality) {
        if (!(file instanceof File) || typeof squareSide !== 'number' || squareSide < 64 || typeof quality !== 'number') {
            return Promise.reject(new Error('bad_args'));
        }

        var blobUrl = URL.createObjectURL(file);

        return new Promise(function(resolve, reject) {
            var img = new Image();

            img.onload = function() {
                var w = img.naturalWidth || img.width || 0;
                var h = img.naturalHeight || img.height || 0;

                if (!w || !h) {
                    reject(new Error('no_dimensions'));

                    return;
                }

                var S = squareSide;
                var scale = Math.max(S / w, S / h);
                var crop = S / scale;
                var sx = Math.max(0, (w - crop) / 2);
                var sy = Math.max(0, (h - crop) / 2);
                var canvas = document.createElement('canvas');

                canvas.width = S;
                canvas.height = S;

                var ctx = canvas.getContext('2d');

                if (!ctx) {
                    reject(new Error('no_canvas'));

                    return;
                }

                ctx.drawImage(img, sx, sy, crop, crop, 0, 0, S, S);

                try {
                    resolve(canvas.toDataURL('image/jpeg', quality));
                } catch (eCanvas) {
                    reject(eCanvas);
                }
            };

            img.onerror = function() {
                reject(new Error('img_error'));
            };

            img.src = blobUrl;
        }).then(
            function(dataUrl) {
                URL.revokeObjectURL(blobUrl);

                return dataUrl;
            },
            function(err) {
                URL.revokeObjectURL(blobUrl);

                throw err;
            }
        );
    }

    function getAiImageSearchAjaxUrl() {
        if (typeof askagentoAiImageSearchFront !== 'undefined' && askagentoAiImageSearchFront.ajaxUrl) {
            return askagentoAiImageSearchFront.ajaxUrl;
        }

        if (typeof askagentoFront !== 'undefined' && askagentoFront.ajaxUrl) {
            return askagentoFront.ajaxUrl;
        }

        return '';
    }

    function getAiImageSearchNonce() {
        if (typeof askagentoAiImageSearchFront !== 'undefined' && askagentoAiImageSearchFront.nonce) {
            return askagentoAiImageSearchFront.nonce;
        }

        return '';
    }

    function bindAiImageSearch(root) {
        var box = root.querySelector('.askagento-ai-image-search');

        if (!box) {
            return;
        }

        // Prefer credentials embedded directly in the HTML (data attributes) so
        // the widget works even when askagentoAiImageSearchFront is absent.
        var ajaxUrl   = box.getAttribute('data-ajax-url')   || getAiImageSearchAjaxUrl();
        var nonceVal  = box.getAttribute('data-nonce')       || getAiImageSearchNonce();
        var searchUrl = box.getAttribute('data-search-url')  || (typeof askagentoAiImageSearchFront !== 'undefined' ? askagentoAiImageSearchFront.searchUrl  : '');
        var siteId    = box.getAttribute('data-site-id')     || (typeof askagentoAiImageSearchFront !== 'undefined' ? askagentoAiImageSearchFront.siteId     : '');
        var apiKey    = box.getAttribute('data-api-key')     || (typeof askagentoAiImageSearchFront !== 'undefined' ? askagentoAiImageSearchFront.apiKey      : '');

        if (!ajaxUrl || !nonceVal) {
            return;
        }

        var fileInput = root.querySelector('input[type="file"]');

        if (!fileInput) {
            return;
        }

        var camBtn = box.querySelector('.askagento-ai-image-search-camera');
        var statusEl = box.querySelector('.askagento-ai-image-search-status');
        var list =
            box.querySelector('.askagento-ai-image-search-results') || box.querySelector('.askagento-ai-text-search-results');

        var maxPx = parseInt(box.getAttribute('data-max-raster-px'), 10)
            || (typeof askagentoAiImageSearchFront !== 'undefined' && askagentoAiImageSearchFront.maxRasterPx
                ? parseInt(askagentoAiImageSearchFront.maxRasterPx, 10)
                : 260);

        if (!maxPx || maxPx < 64) {
            maxPx = 260;
        }

        var resultLimit = parseInt(box.getAttribute('data-result-limit'), 10)
            || (typeof askagentoAiImageSearchFront !== 'undefined' && askagentoAiImageSearchFront.resultLimit
                ? parseInt(askagentoAiImageSearchFront.resultLimit, 10)
                : 12);

        var lim = Number.isFinite(resultLimit) ? Math.min(50, Math.max(1, resultLimit)) : 12;

        function msg(attr, fallback) {
            return box.getAttribute(attr) || fallback;
        }

        function setLoading(on) {
            box.classList.toggle('askagento-ai-image-search-loading', on);

            if (camBtn) {
                camBtn.disabled = on;
            }

            fileInput.disabled = on;
        }

        function renderRows(rows) {
            if (!list) {
                return;
            }

            list.innerHTML = '';
            var empty = !rows || !rows.length;

            list.classList.toggle('askagento-ai-text-search-results--empty', empty);

            if (empty) {
                if (statusEl) {
                    statusEl.textContent = msg('data-msg-empty', '');
                }

                return;
            }

            if (statusEl) {
                statusEl.textContent = '';
            }

            rows.forEach(function(row) {
                var li = document.createElement('li');

                li.className = 'askagento-ai-text-tile';
                li.setAttribute('role', 'listitem');

                var a = document.createElement('a');

                a.href = row.permalink || '#';
                a.className = 'askagento-ai-text-tile-link';

                var imgWrap = document.createElement('div');

                imgWrap.className = 'askagento-ai-text-tile-media';

                if (row.image_url) {
                    var img = document.createElement('img');

                    img.src = row.image_url;
                    img.alt = '';
                    img.loading = 'lazy';
                    img.decoding = 'async';
                    imgWrap.appendChild(img);
                } else {
                    imgWrap.classList.add('askagento-ai-text-tile-media--placeholder');
                }

                var body = document.createElement('div');

                body.className = 'askagento-ai-text-tile-body';

                var title = document.createElement('div');

                title.className = 'askagento-ai-text-tile-title';
                title.textContent = row.title || '';

                body.appendChild(title);

                if (row.price_html) {
                    var priceEl = document.createElement('div');

                    priceEl.className = 'askagento-ai-text-tile-price woocommerce';
                    priceEl.innerHTML = row.price_html;
                    body.appendChild(priceEl);
                }

                a.appendChild(imgWrap);
                a.appendChild(body);
                li.appendChild(a);
                list.appendChild(li);
            });
        }

        function runUpload(file) {
            if (!file) {
                return;
            }

            setLoading(true);

            if (statusEl) {
                statusEl.textContent = msg('data-msg-working', '');
            }

            jpegDataUrlFromFileForPf(file, maxPx, 0.95)
                .then(function(dataUrl) {
                    var comma = String(dataUrl).indexOf(',');
                    var b64 = comma >= 0 ? String(dataUrl).slice(comma + 1) : '';

                    if (b64.length < 33) {
                        throw new Error('short');
                    }

                    // Direct browser→API path: bypasses WordPress for the image payload
                    // so large base64 bodies never reach admin-ajax.php (avoids WAF/mod_security blocks).
                    if (searchUrl && siteId && apiKey) {
                        return fetch(searchUrl, {
                            method: 'POST',
                            headers: {
                                'Content-Type':        'application/json',
                                'X-Askagento-Site-Id': siteId,
                                'X-Askagento-Api-Key': apiKey,
                            },
                            body: JSON.stringify({
                                modality: 'image',
                                image_base64: b64,
                                limit: lim,
                            }),
                        })
                        .then(function(r) { return r.json(); })
                        .then(function(apiData) {
                            var apiRows = Array.isArray(apiData.results) ? apiData.results : [];
                            var ids = apiRows.map(function(r) { return r.product_id; }).filter(Boolean);

                            if (!ids.length) {
                                renderRows([]);
                                return;
                            }

                            // Enrich product IDs with WooCommerce permalink + price (tiny payload).
                            var fd = new FormData();
                            fd.append('action', 'askagento_ai_search_enrich');
                            fd.append('nonce', nonceVal);
                            ids.forEach(function(pid) { fd.append('product_ids[]', pid); });

                            return fetch(ajaxUrl, { method: 'POST', body: fd })
                                .then(function(r) { return r.json(); })
                                .then(function(enrichData) {
                                    var enriched = {};
                                    if (enrichData && enrichData.success && enrichData.data && enrichData.data.results) {
                                        enrichData.data.results.forEach(function(r) {
                                            if (r.product_id != null) {
                                                enriched[String(r.product_id)] = r;
                                            }
                                        });
                                    }
                                    // Merge API row (title, image_url, distance) with WC data (permalink, price_html).
                                    var merged = apiRows.map(function(r) {
                                        var wc = enriched[String(r.product_id)] || {};
                                        return Object.assign({}, r, wc, { product_id: r.product_id });
                                    });
                                    renderRows(merged);
                                });
                        });
                    }

                    // Fallback: post image through WordPress admin-ajax.php (may be blocked by WAF).
                    var fd = new FormData();
                    fd.append('action', 'askagento_ai_image_search');
                    fd.append('nonce', nonceVal);
                    fd.append('image_base64', b64);
                    fd.append('limit', String(lim));

                    return fetch(ajaxUrl, { method: 'POST', body: fd })
                        .then(function(response) {
                            return response.text().then(function(text) {
                                return { status: response.status, text: text };
                            });
                        })
                        .then(function(payload) {
                            var text = payload.text || '';
                            var data;

                            try {
                                data = text ? JSON.parse(text) : {};
                            } catch (eJson) {
                                renderRows([]);
                                if (statusEl) {
                                    statusEl.textContent = msg('data-msg-error', '') + ' (HTTP ' + payload.status + ')';
                                }
                                return;
                            }

                            if (!data || !data.success) {
                                var errMsg = msg('data-msg-error', '');
                                if (data && data.data && data.data.message) {
                                    errMsg = data.data.message;
                                }
                                renderRows([]);
                                if (statusEl) {
                                    statusEl.textContent = errMsg;
                                }
                                return;
                            }

                            renderRows(data.data && data.data.results ? data.data.results : []);
                        });
                })
                .catch(function(err) {
                    renderRows([]);

                    if (statusEl) {
                        if (err && err.name === 'AbortError') {
                            statusEl.textContent = msg('data-msg-error', '');
                        } else if (err && err.message && String(err.message) !== 'short') {
                            statusEl.textContent = msg('data-msg-error', '') + ' (' + String(err.message) + ')';
                        } else {
                            statusEl.textContent = msg('data-msg-error', '');
                        }
                    }
                })
                .finally(function() {
                    setLoading(false);
                    fileInput.value = '';
                });
        }

        if (camBtn) {
            camBtn.addEventListener('click', function() {
                fileInput.click();
            });
        }

        fileInput.addEventListener('change', function() {
            var f = fileInput.files && fileInput.files[0];

            runUpload(f || null);
        });

        // Sample photos ("…or try a sample"): fetch the bundled image, wrap it in a
        // File and run the same upload flow so visitors can try image search without
        // a photo of their own (mirrors the v1/v2 landing-page demo).
        function runSample(url) {
            if (!url) {
                return;
            }

            setLoading(true);

            if (statusEl) {
                statusEl.textContent = msg('data-msg-working', '');
            }

            fetch(url)
                .then(function(r) {
                    if (!r.ok) {
                        throw new Error('sample_fetch');
                    }

                    return r.blob();
                })
                .then(function(blob) {
                    var name = String(url).split('/').pop().replace(/\?.*$/, '') || 'sample.png';
                    var type = blob.type && blob.type.indexOf('image/') === 0 ? blob.type : 'image/png';
                    var file = new File([blob], name, { type: type });

                    runUpload(file);
                })
                .catch(function() {
                    setLoading(false);

                    if (statusEl) {
                        statusEl.textContent = msg('data-msg-error', '');
                    }
                });
        }

        var sampleBtns = box.querySelectorAll('.askagento-ai-image-search-sample');

        Array.prototype.forEach.call(sampleBtns, function(sampleBtn) {
            sampleBtn.addEventListener('click', function() {
                runSample(sampleBtn.getAttribute('data-sample-url') || '');
            });
        });
    }

    // Browser back/forward
    window.addEventListener('popstate', function() {
        var reload = false;
        document.querySelectorAll('.askagento-filter[data-askagento-config]').forEach(function(el) {
            var c = parsePfConfig(el);
            if (c && c.ajax) {
                reload = true;
            }
        });
        if (!reload && typeof askagentoFront !== 'undefined' && askagentoFront.ajax) {
            reload = true;
        }
        if (reload) {
            window.location.reload();
        }
    });
    
})();
