/* global jQuery, askagentoAiSearchAdmin */
(function ($) {
    'use strict';

    function escapeHtml(value) {
        return $('<div>').text(value == null ? '' : String(value)).html();
    }

    function normCatalogTitleRough(value) {
        if (value == null) {
            return '';
        }
        return String(value)
            .replace(/<[^>]*>/gi, '')
            .replace(/\s+/g, ' ')
            .trim()
            .toLowerCase();
    }

    /**
     * Last-line duplicate removal (ids/SKU/GTIN + title+tied-distance fallback for cloned catalogue rows).
     */
    function stripSampleFromResultRows(rows, sample, skuNorm, guidNorm, titleNorm, minFiniteDist) {
        if (!Array.isArray(rows)) {
            return [];
        }

        var sku = (skuNorm || '').trim().toLowerCase();
        var guid = (guidNorm || '').trim().toLowerCase();
        var titleN = normCatalogTitleRough(titleNorm || '');
        var minParsed = minFiniteDist == null ? NaN : Number(minFiniteDist);
        var minD = Number.isFinite(minParsed) ? minParsed : null;
        var epsilon = 1e-4;
        var sid = sample && sample.product_id != null ? Number(sample.product_id, 10) : NaN;

        return rows.filter(function (row) {
            var rid = row.product_id != null ? Number(row.product_id, 10) : NaN;

            if (Number.isFinite(sid) && Number.isFinite(rid) && rid === sid) {
                return false;
            }

            if (sku) {
                var rk = row.sku != null ? String(row.sku).trim().toLowerCase() : '';

                if (rk !== '' && rk === sku) {
                    return false;
                }
            }

            if (guid) {
                var rg =
                    row.global_unique_id != null ? String(row.global_unique_id).trim().toLowerCase() : '';

                if (rg !== '' && rg === guid) {
                    return false;
                }
            }

            if (minD !== null && titleN) {
                var rt = normCatalogTitleRough(row.title);
                var rd =
                    row.distance != null && Number.isFinite(Number(row.distance))
                        ? Number(row.distance)
                        : null;

                if (rd !== null && rt !== '' && rt === titleN && Math.abs(rd - minD) <= epsilon) {
                    return false;
                }
            }

            return true;
        });
    }

    function minFiniteDistanceFromRows(rows) {
        if (!Array.isArray(rows)) {
            return null;
        }

        var best = null;

        rows.forEach(function (row) {
            var d = row.distance != null ? Number(row.distance) : NaN;

            if (Number.isFinite(d)) {
                best = best === null ? d : Math.min(best, d);
            }
        });

        return best;
    }

    function tileHtml(row, variant) {
        var tileClass = 'askagento-ai-search-admin-tile askagento-ai-search-admin-tile--text';

        if (variant === 'querySample') {
            tileClass += ' askagento-ai-search-admin-tile--query-sample';
        }

        var thumb = '';

        if (row.image_url) {
            thumb =
                '<img class="askagento-ai-search-admin-thumb" src="' +
                escapeHtml(row.image_url) +
                '" alt="" loading="lazy">';
        }

        var priceHtml = '';

        if (row.price_html) {
            priceHtml =
                '<div class="askagento-ai-search-admin-price woocommerce">' + row.price_html + '</div>';
        }

        var snippet =
            row.description_snippet != null && String(row.description_snippet).trim() !== ''
                ? String(row.description_snippet).trim()
                : '';
        var snippetBlock = '';

        if (snippet !== '') {
            snippetBlock =
                '<div class="askagento-ai-search-admin-snippet-wrap"><span>' + escapeHtml(snippet) + '</span></div>';
        }

        return (
            '<li class="' + tileClass + '">' +
            '<div class="askagento-ai-search-admin-tile-inner">' +
            '<div class="askagento-ai-search-admin-media">' +
            thumb +
            '</div>' +
            '<div class="askagento-ai-search-admin-meta">' +
            '<span class="askagento-ai-search-admin-title">' +
            escapeHtml(row.title || '') +
            '</span>' +
            snippetBlock +
            priceHtml +
            '</div></div></li>'
        );
    }

    $(function () {
        var btn = $('#askagento-ai-search-check-status');
        var freeBtn = $('#askagento-ai-search-free-text-run');
        var freeTa = $('#askagento-ai-search-free-text');

        if (!btn.length && !freeBtn.length) {
            return;
        }

        var outBox = $('#askagento-ai-search-status-out');
        var listing = $('#askagento-ai-search-results-list');
        var queryBlock = $('#askagento-ai-search-query-sample-block');
        var queryList = $('#askagento-ai-search-query-sample-list');
        var matchesHeading = $('#askagento-ai-search-matches-heading');
        var splitPane = $('#askagento-ai-search-diagnostics-split');

        var freeOut = $('#askagento-ai-search-freetext-status-out');
        var freeListing = $('#askagento-ai-search-freetext-results-list');
        var freeMatchesHeading = $('#askagento-ai-search-freetext-matches-heading');
        var freeShortHint = $('#askagento-ai-search-freetext-short-hint');

        function setDiagnosticsSplitVisible(on) {
            splitPane.toggleClass('askagento-ai-search-diagnostics-split--visible', !!on);
        }

        /**
         * @param {object} job
         * @param {JQuery} job.btn
         * @param {JQuery} job.outBox
         * @param {JQuery} job.listing
         * @param {JQuery} [job.matchesHeading]
         * @param {JQuery} [job.queryBlock]
         * @param {JQuery} [job.queryList]
         * @param {JQuery} [job.splitPane]
         * @param {object} [job.ajaxExtra]
         * @param {string} [job.workingMsg]
         * @param {boolean} [job.useDiagnosticsSplit]
         * @param {boolean} [job.listingStartsHidden]
         * @param {number} [job.onlyIfSeq] When set with getLatestSeq, abort if sequence changed (debounced live search).
         * @param {function(): number} [job.getLatestSeq]
         */
        async function runAdminTextSearch(job) {
            var $btn = job.btn;
            var startedAt = Date.now();
            var i18n = askagentoAiSearchAdmin.i18n || {};
            var $outBox = job.outBox;
            var $listing = job.listing;
            var $matchesHeading = job.matchesHeading;
            var $queryBlock = job.queryBlock;
            var $queryList = job.queryList;
            var $splitPane = job.splitPane;
            var useSplit = !!job.useDiagnosticsSplit && $splitPane && $splitPane.length;
            var listingStartsHidden = !!job.listingStartsHidden;
            var staleGuard =
                typeof job.getLatestSeq === 'function' && typeof job.onlyIfSeq === 'number';
            var staleAborted = false;

            function isStale() {
                return staleGuard && job.onlyIfSeq !== job.getLatestSeq();
            }

            if (listingStartsHidden && freeShortHint.length) {
                freeShortHint.hide();
            }

            $btn.prop('disabled', true);
            $outBox.html('<p>' + escapeHtml(job.workingMsg || i18n.working || '') + '</p>');

            if (useSplit) {
                $splitPane.removeClass('askagento-ai-search-diagnostics-split--visible');
                if ($queryBlock && $queryBlock.length) {
                    $queryBlock.hide();
                }
            }

            if ($matchesHeading && $matchesHeading.length) {
                $matchesHeading.hide();
            }

            if ($queryList && $queryList.length) {
                $queryList.empty();
            }

            $listing.empty();

            if (listingStartsHidden) {
                $listing.hide();
            }

            try {
                var ajaxData = {
                    action: 'askagento_ai_search_admin_run',
                    nonce: askagentoAiSearchAdmin.nonce
                };

                if (job.ajaxExtra && typeof job.ajaxExtra === 'object') {
                    Object.assign(ajaxData, job.ajaxExtra);
                }

                var resp = await $.ajax({
                    url: askagentoAiSearchAdmin.ajaxUrl,
                    method: 'POST',
                    data: ajaxData,
                    dataType: 'json'
                });

                if (isStale()) {
                    staleAborted = true;
                    $outBox.empty();

                    if (listingStartsHidden) {
                        $listing.empty().hide();
                    }

                    if ($matchesHeading && $matchesHeading.length) {
                        $matchesHeading.hide();
                    }

                    return;
                }

                if (!resp.success) {
                    var err =
                        resp.data && resp.data.message ? resp.data.message : i18n.failed || '';

                    if (useSplit && $splitPane && $splitPane.length) {
                        $splitPane.removeClass('askagento-ai-search-diagnostics-split--visible');
                    }

                    if ($queryBlock && $queryBlock.length) {
                        $queryBlock.hide();
                    }

                    if ($matchesHeading && $matchesHeading.length) {
                        $matchesHeading.hide();
                    }

                    if ($queryList && $queryList.length) {
                        $queryList.empty();
                    }

                    $listing.empty();

                    if (listingStartsHidden) {
                        $listing.hide();
                    }

                    $outBox.html(
                        '<p class="notice notice-error" style="padding:8px 12px;">' + escapeHtml(err) + '</p>'
                    );

                    return;
                }

                var d = resp.data || {};
                var sampleItem = d.sample_query_item || null;
                var skuNorm =
                    d.sample_product_sku != null ? String(d.sample_product_sku).trim().toLowerCase() : '';
                var guidNorm =
                    d.sample_global_unique_id != null
                        ? String(d.sample_global_unique_id).trim().toLowerCase()
                        : '';
                var visMax = parseInt(d.visible_max, 10);
                var visCap = Number.isFinite(visMax) ? Math.min(50, Math.max(1, visMax)) : 3;
                var rawRows = Array.isArray(d.results) ? d.results : [];

                if (isStale()) {
                    staleAborted = true;
                    $outBox.empty();

                    if (listingStartsHidden) {
                        $listing.empty().hide();
                    }

                    if ($matchesHeading && $matchesHeading.length) {
                        $matchesHeading.hide();
                    }

                    return;
                }
                var minD = minFiniteDistanceFromRows(rawRows);
                var visibleResults = stripSampleFromResultRows(
                    rawRows,
                    sampleItem,
                    skuNorm,
                    guidNorm,
                    d.sample_title_normalized,
                    minD
                ).slice(0, visCap);

                $outBox.empty();

                if (useSplit && $queryBlock && $queryList && sampleItem && sampleItem.product_id) {
                    $queryList.empty().append(tileHtml(sampleItem, 'querySample'));
                    $queryBlock.show();
                } else if ($queryList && $queryList.length) {
                    $queryList.empty();

                    if ($queryBlock && $queryBlock.length) {
                        $queryBlock.hide();
                    }
                }

                if (visibleResults.length) {
                    if ($matchesHeading && $matchesHeading.length) {
                        $matchesHeading.show();
                    }

                    if (listingStartsHidden) {
                        $listing.show();
                    }

                    visibleResults.forEach(function (row) {
                        $listing.append(tileHtml(row));
                    });
                } else if ($matchesHeading && $matchesHeading.length) {
                    $matchesHeading.hide();

                    if (listingStartsHidden) {
                        $listing.hide();
                    }
                }

                if (useSplit && $splitPane && $splitPane.length && $queryList && $queryList.length) {
                    setDiagnosticsSplitVisible(
                        $queryList.children().length > 0 || $listing.children().length > 0
                    );
                }
            } catch (err) {
                var msg;

                if (err && err.name === 'AbortError') {
                    msg = i18n.timedOut || '';
                } else if (err && err.name === 'TypeError') {
                    var surl = String(askagentoAiSearchAdmin.searchUrl || '');

                    if (window.location.protocol === 'https:' && surl.indexOf('http://') === 0) {
                        msg = (i18n.requestFailed || '') + ' ' + (i18n.httpsApiRequired || '').trim();
                    } else {
                        msg = (i18n.requestFailed || '') + (err.message ? ' (' + String(err.message) + ')' : '');
                    }
                } else if (err && err.message) {
                    msg = String(err.message);
                } else {
                    msg = i18n.requestFailed || '';
                }

                if (useSplit && $splitPane && $splitPane.length) {
                    $splitPane.removeClass('askagento-ai-search-diagnostics-split--visible');
                }

                if ($queryBlock && $queryBlock.length) {
                    $queryBlock.hide();
                }

                if ($matchesHeading && $matchesHeading.length) {
                    $matchesHeading.hide();
                }

                if ($queryList && $queryList.length) {
                    $queryList.empty();
                }

                $listing.empty();

                if (listingStartsHidden) {
                    $listing.hide();
                }

                $outBox.html(
                    '<p class="notice notice-error" style="padding:8px 12px;">' + escapeHtml(msg) + '</p>'
                );
            } finally {
                if (staleAborted) {
                    $btn.prop('disabled', false);
                    return;
                }

                var elapsedSec = (Date.now() - startedAt) / 1000;
                var pingSec = elapsedSec.toFixed(1);
                var pingHtml =
                    '<p class="askagento-ai-search-admin-ping">' +
                    escapeHtml(i18n.ping || '') +
                    ' <strong>' +
                    escapeHtml(pingSec) +
                    '</strong> ' +
                    escapeHtml(i18n.pingUnit || 's') +
                    '</p>';

                $outBox.append(pingHtml);
                $btn.prop('disabled', false);
            }
        }

        if (btn.length) {
            btn.on('click', function () {
                runAdminTextSearch({
                    btn: btn,
                    outBox: outBox,
                    listing: listing,
                    matchesHeading: matchesHeading,
                    queryBlock: queryBlock,
                    queryList: queryList,
                    splitPane: splitPane,
                    useDiagnosticsSplit: true,
                    workingMsg: (askagentoAiSearchAdmin.i18n || {}).working
                });
            });
        }

        if (
            freeBtn.length &&
            freeTa.length &&
            freeOut.length &&
            freeListing.length &&
            freeMatchesHeading.length
        ) {
            var freeSeq = 0;
            var freeDebounceTimer = null;

            function nextFreeSeq() {
                freeSeq += 1;
                return freeSeq;
            }

            function freeTextTooShortUi() {
                freeOut.empty();
                freeListing.empty().hide();
                freeMatchesHeading.hide();

                if (freeShortHint.length) {
                    freeShortHint.show();
                }
            }

            function liveSearchEnabled() {
                if (!askagentoAiSearchAdmin || askagentoAiSearchAdmin.liveEnabled === undefined) {
                    return true;
                }

                return (
                    askagentoAiSearchAdmin.liveEnabled !== false &&
                    askagentoAiSearchAdmin.liveEnabled !== 0 &&
                    askagentoAiSearchAdmin.liveEnabled !== '0'
                );
            }

            function liveDebounceMs() {
                var ms = parseInt(askagentoAiSearchAdmin.liveDebounceMs, 10);

                if (!ms || ms < 1) {
                    return 900;
                }

                return ms;
            }

            function runFreeTextSearchNow(extraJob) {
                var i18n = askagentoAiSearchAdmin.i18n || {};
                var raw = freeTa.length ? String(freeTa.val() || '') : '';
                var trimmed = raw.trim();

                if (trimmed.length < 2) {
                    freeTextTooShortUi();
                    return;
                }

                var job = {
                    btn: freeBtn,
                    outBox: freeOut,
                    listing: freeListing,
                    matchesHeading: freeMatchesHeading,
                    ajaxExtra: { free_text: raw },
                    workingMsg: i18n.workingFreeText,
                    listingStartsHidden: true
                };

                if (extraJob && typeof extraJob === 'object') {
                    Object.assign(job, extraJob);
                }

                runAdminTextSearch(job);
            }

            freeTa.on('input', function () {
                if (!liveSearchEnabled()) {
                    return;
                }

                window.clearTimeout(freeDebounceTimer);
                freeDebounceTimer = null;

                var raw = freeTa.length ? String(freeTa.val() || '') : '';
                var trimmed = raw.trim();

                if (trimmed.length < 2) {
                    nextFreeSeq();
                    freeTextTooShortUi();
                    return;
                }

                if (freeShortHint.length) {
                    freeShortHint.hide();
                }

                freeOut.empty();

                freeDebounceTimer = window.setTimeout(function () {
                    freeDebounceTimer = null;
                    var runId = nextFreeSeq();

                    runFreeTextSearchNow({
                        onlyIfSeq: runId,
                        getLatestSeq: function () {
                            return freeSeq;
                        }
                    });
                }, liveDebounceMs());
            });

            freeTa.on('keydown', function (e) {
                if (e.key !== 'Enter') {
                    return;
                }

                e.preventDefault();
                window.clearTimeout(freeDebounceTimer);
                freeDebounceTimer = null;
                nextFreeSeq();
                runFreeTextSearchNow();
            });

            freeBtn.on('click', function () {
                window.clearTimeout(freeDebounceTimer);
                freeDebounceTimer = null;
                nextFreeSeq();
                runFreeTextSearchNow();
            });
        }
    });
})(jQuery);
