var bidspiritApi;

// Suppress PayTrace env_includes errors
(function() {
    var originalOnError = window.onerror;
    window.onerror = function(message, source, lineno, colno, error) {
        if (source && source.indexOf('env_includes') !== -1 && source.indexOf('paytrace.com') !== -1) {
            console.warn('[PayTrace] Suppressed broken dependency error:', message);
            return true; // Suppress error
        }
        if (originalOnError) {
            return originalOnError.apply(this, arguments);
        }
        return false;
    };
})();

(function ($) {
    var BIDSPIRIT_SERVER = window.bidSpiritServer,
        BIDSPIRIT_API_BASE = BIDSPIRIT_SERVER + "api/thirdparty/v1/",
        REST_API_BASE = "/wp-json/bidspirit/v1/",
        LANG = window.bidSpiritLang,
        currencySymbol = window.bidSpiritCurrency !== "" ? window.bidSpiritCurrency : "$",
        bidspiritSessionId,
        bidspiritAuthToken,
        bidspiritUser,
        currentAuctionNumber,
        currentLotIndex,
        allIncrementsPrices = null,
        currentItemInfoResponse = null,
        currentItemInfo = null,
        auctionApprovalState = null,
        countriesList = null,
        auctionHouseData = {
            disclaimer: null,
            email: null,
            info: null,
            name: null,
            noVatByDefault: null,
            phone: null,
            noVatOnCommission: null,

            /**
             * Depricated:
             * enablePrebidsUnderStartPrice: null,
             * houseCommissionVatRule: null,
             * requireIdPhoto: null,
             * idPhotoUploadRequired: null,
             * vat: null
             **/
        },
        auctionInfo = {
            approvalRequired: null,
            paymentMethodRequired: null,
            absenteeBidsEnabled: null,
            address: null,
            automaticAuction: null,
            commission: null,
            commissionInfo: null,
            currency: null,
            days: null,
            displayStartPriceInCatalog: null,
            id: null,
            info: null,
            lastCatalogUpdate: null,
            name: null,
            number: null,
            showEstimatedPriceInItemsList: null,
            state: null,
        },
        auctionItemInfo = {},
        paymentMethods = [],
        auctionSettingsData = {
            requireUserId: null,
            requireTaxNumber: null,
            documentUrlBase: null,
            stripePublicKey: null,
            bidspiritPortal: null,
            creditCardProvider: null,
            alertsEnabled: null,
            minimumForUsersCallRequests: null,
            enableUsersCallRequests: null,
            proxyDomain: null,
            houseInfo: null,
            autoPaymentDays: null,
            enablePrebidsUnderStartPrice: null,
            houseCommissionVatRule: null,
            requireIdPhoto: null,
            idPhotoUploadRequired: null,
            vat: null,
            hideSoldPrice: true,
        },
        imageBlank = (typeof AuctionForgePlugin !== "undefined" && AuctionForgePlugin.imageBlank) ? AuctionForgePlugin.imageBlank : "/wp-content/plugins/uco-auctions/img/not_found.jpg",
        triggerClass = "is-load-earlier";
    bidspiritApi = {
        lang: LANG,
        getBidspiritSessionId: function () {
            return bidspiritSessionId;
        },
        setBidspiritSessionId: function (sessionId) {
            if (sessionId === undefined) {
                try {
                    sessionId = localStorage.getItem("bidspiritSessionId") || "";
                } catch (e) {
                    console.error("Local storage disabled");
                }
            }

            bidspiritSessionId = sessionId;
        },
        getAuthToken: function (apiAction) {
            if (apiAction !== undefined && apiAction === "users/initSession" && bpGetQueryParams("authToken") !== null) {
                return bpGetQueryParams("authToken");
            }

            try {
                bidspiritAuthToken = localStorage.getItem("bidspiritAuthToken");
            } catch (e) {
                console.error("Local storage disabled");
                bidspiritAuthToken = "";
            }

            return bidspiritAuthToken;
        },
        setAuthToken: function (authToken) {
            try {
                localStorage.setItem("bidspiritAuthToken", authToken);
            } catch (e) {
                console.error("Local storage disabled");
            }

            bidspiritAuthToken = authToken;
        },
        getBidspiritUser: function () {
            return bidspiritUser;
        },
        setBidspiritUser: function (user) {
            bidspiritUser = user;
            let successMessage = "";

            if (bidspiritUser !== undefined) {
                if (bidspiritUser.honorific === undefined) {
                    bidspiritUser.honorific = "";
                }

                if (bidspiritUser.firstName === undefined) {
                    bidspiritUser.firstName = "";
                }

                if (bidspiritUser.lastName === undefined) {
                    bidspiritUser.lastName = "";
                }

                successMessage = window.bs_lang.login_success_hello + ", " + bidspiritUser.firstName;

                if (bidspiritUser.honorific !== "") {
                    successMessage = window.bs_lang.login_success_full_hello.replace(/%s1/, bidspiritUser.honorific).replace(/%s2/, bidspiritUser.firstName).replace(/%s3/, bidspiritUser.lastName);
                }

                if (window.bs_lang.login_success_hello_custom !== "" && bidspiritUser.honorific !== "") {
                    successMessage = window.bs_lang.login_success_hello_custom.replace(/%s1/, bidspiritUser.honorific).replace(/%s2/, bidspiritUser.firstName).replace(/%s3/, bidspiritUser.lastName);
                } else if (window.bs_lang.login_success_hello_custom_default !== "" && bidspiritUser.honorific === "") {
                    successMessage = window.bs_lang.login_success_hello_custom_default.replace(/%s1/, bidspiritUser.firstName).replace(/%s2/, bidspiritUser.lastName);
                }

                bidspiritUser.successMessage = successMessage;
            }
        },
        getAuctionApprovalState: function () {
            return auctionApprovalState;
        },
        setAuctionApprovalState: function (value) {
            auctionApprovalState = value;
        },
        getCountriesList: function () {
            return countriesList;
        },
        setCountriesList: function (value) {
            countriesList = value;
        },
        getAuctionHouseData: function () {
            return auctionHouseData;
        },
        setAuctionHouseData: function (value) {
            auctionHouseData = value;
        },
        getAuctionSettingsData: function () {
            return auctionSettingsData;
        },
        setAuctionSettingsData: function (value) {
            auctionSettingsData = value;
        },
        getAuctionInfo: function () {
            return auctionInfo;
        },
        setAuctionInfo: function (value) {
            if (value.currency !== undefined) {
                currencySymbol = value.currency;
            }
            auctionInfo = value;
        },
        getAuctionItemInfo: function () {
            return auctionItemInfo;
        },
        setAuctionItemInfo: function (value) {
            auctionItemInfo = value;
        },
        setIncrementsPrices: function (callback) {
            if (allIncrementsPrices === null) {
                allIncrementsPrices = bidspiritApi.getAuctionInfo().increments;
            } else {
                callback(allIncrementsPrices);
            }
        },
        getIncrementsPrices: function () {
            return allIncrementsPrices;
        },
        stripeLoad: function (callback) {
            var classTrigger = "stripe-load";

            if (document.body.classList.contains(classTrigger)) {
                callback();
            } else {
                $.getScript("https://js.stripe.com/v3/").done(function (script, textStatus) {
                    callback();
                    console.info(textStatus + " Stripe load");
                    document.body.classList.add(classTrigger);
                }).fail(function (jqxhr, settings, exception) {
                    console.error("Error Stripe load", jqxhr, settings, exception);
                });
            }
        },
        getLinkOnLive() {
            let lat = "";

            if (bidspiritUser !== undefined && bidspiritUser.liveAuctionToken !== undefined) {
                lat = "?lat=" + bidspiritUser.liveAuctionToken;
            }

            return BIDSPIRIT_SERVER + lat;
        },
        auctionSettingsDataInit: function () {
            if (auctionSettingsData.requireUserId === null) {
                bidspiritQuery("settings/getSettings", {
                    sessionId: bidspiritSessionId,
                    language: LANG
                }, function (data) {
                    auctionSettingsData = data.response;
                    bidspiritApi.setAuctionSettingsData(auctionSettingsData);
                });
            }
        },
        bidspiritQuery: bidspiritQuery,
        bidspiritPostQuery: bidspiritPostQuery,
        init: init,
        doLogout: doLogout,
        checkError: checkError,
        initIncrementSteps: initIncrementSteps,
        checkErrorForm: checkErrorForm,
        auctionInfoInit: auctionInfoInit,
        hangUpEvent: hangUpEvent,
        saveFirebaseUser: saveFirebaseUser,
        updateUserDisplay: updateUserDisplay,
        updateDisplay: updateDisplay,
        loginLink: loginLink,
        submitRegister: submitRegister,
        getDataForm: getDataForm
    };

    function ajaxQuery(params, apiAction, data, callback, errorCallback, alwaysCallback) {
        $.ajax(params).done(function (response) {
            if (callback !== undefined) {
                callback(response);
            }
        }).fail(function () {
            if (errorCallback !== undefined) {
                errorCallback();
            }
        }).always(function () {
            if (alwaysCallback !== undefined) {
                alwaysCallback();
            }
        });
    }

    function restQuery(apiCall, method, data, callback) {
        var xhttp = new XMLHttpRequest();

        xhttp.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                if (callback !== undefined) {
                    callback(this.responseText);
                }
            }
        };

        apiCall = REST_API_BASE + apiCall + "?" + new URLSearchParams(data).toString();
        xhttp.open(method, apiCall, true);
        xhttp.setRequestHeader("Content-type", "application/json");
        xhttp.send();
    }

    function bidspiritQuery(apiAction, data, callback, errorCallback, alwaysCallback) {
        if (bpGetQueryParams("sessionId") !== null) {
            data.sessionId = bpGetQueryParams("sessionId");
        }

        ajaxQuery({
            url: BIDSPIRIT_API_BASE + apiAction + ".api",
            data: data,
            timeout: 0,
            beforeSend: function (request) {
                request.setRequestHeader("BIDSPIRIT-AUTH-TOKEN", bidspiritApi.getAuthToken(apiAction));
            },
            xhrFields: {
                withCredentials: true
            }
        }, apiAction, data, callback, errorCallback, alwaysCallback);
    }

    function bidspiritPostQuery(apiAction, data, callback, errorCallback, alwaysCallback) {
        if (bpGetQueryParams("sessionId") !== null) {
            data.sessionId = bpGetQueryParams("sessionId");
        }

        ajaxQuery({
            url: BIDSPIRIT_API_BASE + apiAction + ".api",
            data: data,
            type: "POST",
            timeout: 0,
            beforeSend: function (request) {
                request.setRequestHeader("BIDSPIRIT-AUTH-TOKEN", bidspiritApi.getAuthToken(apiAction));
            },
            xhrFields: {
                withCredentials: true
            }
        }, apiAction, data, callback, errorCallback, alwaysCallback);
    }

    function hangUpEvent(name, data, target) {
        var event = jQuery.Event(name);
        event.response = data;

        if (target === undefined) {
            $("body").trigger(event);
        } else {
            target.trigger(event);
        }
    }

    function compareItemIndex(itemIndex, firstLotIndex, lastLotIndex) {
        return parseInt(itemIndex) >= parseInt(firstLotIndex) && itemIndex <= parseInt(lastLotIndex);
    }

    function initialPostAuctionSaleOpenedUntil(auctionData, lotIndex) {
        let currentAuctionDayIndex = 0,
            postAuctionSaleOpenedUntil = 0;
        if (auctionData.days !== undefined && auctionData.days.length > 1) {
            let indexDetect = false;
            auctionData.days.forEach((elem, index) => {
                if (compareItemIndex(lotIndex, elem.firstLotIndex, elem.lastLotIndex) && !indexDetect) {
                    currentAuctionDayIndex = elem.index - 1;
                    indexDetect = true;
                }
            });

            if (auctionData.days[currentAuctionDayIndex] !== undefined && auctionData.days[currentAuctionDayIndex].postAuctionSaleOpenedUntil !== undefined) {
                postAuctionSaleOpenedUntil = auctionData.days[currentAuctionDayIndex].postAuctionSaleOpenedUntil;
                //console.log("testX2.0");
            } else {
                postAuctionSaleOpenedUntil = 0;
                //console.log("testX2.1");
            }
        } else {
            if (auctionData.days[0] !== undefined && auctionData.days[0].postAuctionSaleOpenedUntil !== undefined) {
                postAuctionSaleOpenedUntil = auctionData.days[0].postAuctionSaleOpenedUntil;
                //console.log("testX3.0");
            } else {
                postAuctionSaleOpenedUntil = 0;
                //console.log("testX3.1");
            }
        }

        return [currentAuctionDayIndex, postAuctionSaleOpenedUntil];
    }

    function urldecode(url) {
        return decodeURIComponent(url.replace(/\+/g, " "));
    }

    function passwordShowAction() {
        let profilePasswordIcons = $(".bp_show_password-action");

        if (profilePasswordIcons.length > 0) {
            profilePasswordIcons.each(function (index, elem) {
                $(elem).off("click", ".bp_show_password").on("click", ".bp_show_password", function (event) {
                    let profilePasswordIcon = event.target,
                        fieldPassword = $(elem).find(".bp-form-control_eye");

                    if (fieldPassword[0].type === "password") {
                        fieldPassword[0].type = "text";
                        profilePasswordIcon.classList.remove("svg-eye");
                        profilePasswordIcon.classList.add("svg-eye-slash");
                    } else {
                        fieldPassword[0].type = "password";
                        profilePasswordIcon.classList.remove("svg-eye-slash");
                        profilePasswordIcon.classList.add("svg-eye");
                    }
                });
            });
        }
    }

    function checkPoint(name, clear) {
        if (clear !== undefined) {
            document.body.classList.remove(name);
            setCookie(name, false, -1);
        } else {
            document.body.classList.add(name);
            setCookie(name, true, 1);
        }
    }

    function setCookie(cname, cvalue, exdays) {
        var d = new Date();

        if (exdays === -1) {
            d.setTime(d.getTime() + exdays);
        } else {
            d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
        }

        var expires = "expires=" + d.toUTCString();
        document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;SameSite=Lax";
    }

    function getCookie(cname) {
        var name = cname + "=",
            data = document.cookie.split(";");

        for (var i = 0; i < data.length; i++) {
            var item = data[i];

            while (item.charAt(0) === " ") {
                item = item.substring(1);
            }

            if (item.indexOf(name) === 0) {
                return item.substring(name.length, item.length);
            }
        }

        return "";
    }

    function addBodyClass(className) {
        // $("body").addClass(className);
        document.body.classList.add(className);
    }

    function searchGetParam(param) {
        var name = param.replace(/[\[\]]/g, "\\$&"),
            regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
            results = regex.exec(window.location.href);

        if (!results) {
            return null;
        }

        if (!results[2]) {
            return "";
        }

        return decodeURIComponent(results[2].replace(/\+/g, " "));
    }

    function fireSwall(message, confirmCallback, deniedCallback) {
        Swal.fire({
            html: message,
            showDenyButton: true,
            showCancelButton: true,
            confirmButtonText: "Ok",
            denyButtonText: "Cancel"
        }).then(result => {
            if (result.isConfirmed) {
                if (confirmCallback !== undefined) {
                    confirmCallback();
                }
            } else if (result.isDenied) {
                if (deniedCallback !== undefined) {
                    deniedCallback();
                }
            }
        });
    }

    function loadTemplate(elem, idTemplate, data, visible, callback, append, prepend) {
        var jElem = $(elem);

        if (typeof elem === "string" && elem.match(/\#/)) {
            elem = elem.replace(/\#/, "");
            jElem = $(document.getElementById(elem));
        }

        var html = _.template(document.getElementById(idTemplate).innerHTML),
            hiddenClass = window.bs_data.hidden_class;

        if (visible) {
            jElem.removeClass(hiddenClass);
        }

        if (append !== undefined) {
            if (prepend !== undefined) {
                jElem.prepend(html(data));
            } else {
                jElem.append(html(data));
            }
        } else {
            jElem.html(html(data));
        }

        if (callback !== undefined) {
            callback();
        }
    }

    function loadTemplateInsert(elem, idTemplate, data, append, prepend, callback) {
        var jElem = $(elem),
            html = _.template(document.getElementById(idTemplate).innerHTML);

        if (append !== undefined) {
            if (prepend !== undefined) {
                jElem.prepend(html(data));
            } else {
                jElem.append(html(data));
            }
        } else {
            jElem.html(html(data));
        }

        if (callback !== undefined) {
            callback();
        }
    }

    function bPcheckError(responseData) {
        if (!responseData || responseData.response == null) {
            noticeSwall(modal, window.bs_lang.error, window.bs_lang.empty_response);
            return true;
        }

        if (responseData.response.errorCode) {
            noticeSwall(window.bs_lang.error, responseData.response.errorCode, responseData.response.errorMessage);

            if (responseData.response.errorCode == "SESSION_ENDED") {
                bidspiritUser = null;
                updateDisplay();
            }

            return true;
        }

        return false;
    }

    function checkError(responseData, modal) {
        if (!responseData || responseData.response.success) {
            return false;
        }

        if (!responseData) {
            noticeSwall(modal, "error", "empty response");
            return true;
        }

        hangUpEvent("bp:check-error", responseData.response);

        if (responseData.response.errorCode) {
            noticeSwall("error", "error", responseData.response.errorMessage);

            if (responseData.response.errorCode === "SESSION_ENDED") {
                bidspiritUser = null;
            }

            console.error(responseData.response.errorMessage);
            return true;
        }

        return false;
    }

    function checkErrorForm(form, responseData) {
        var groupContainerSelector = ".errors-group",
            submitButton = $(form).find("[type=submit]"),
            status = false;
        $(form).find(groupContainerSelector).addClass(window.bs_data.hidden_class);

        if (!!submitButton) {
            submitButton[0].disabled = true;
        }

        function printError(form, message) {
            var groupContainer = $(form).find(groupContainerSelector);

            if (groupContainer.hasClass(window.bs_data.hidden_class)) {
                groupContainer.removeClass(window.bs_data.hidden_class);
            }

            groupContainer.empty().append("<p>" + bp_t(message) + "</p>");

            if (!!submitButton) {
                submitButton[0].disabled = false;
            }
        }

        if (!responseData || responseData.response == null) {
            printError(form, "empty response");
            status = true;
        }

        if (responseData.response.errorCode == "USER_EXIST" && window.bs_lang.user_exist !== undefined) {
            printError(form, window.bs_lang.user_exist);
            status = true;
        } else if (responseData.response.errorCode) {
            printError(form, responseData.response.errorMessage);
            status = true;
        }

        hangUpEvent("bp:checkErrorForm", responseData);
        return status;
    }

    /**
     * @param price
     * @param auctionCommission
     * @param isFull
     * @returns {string}
     * @deprecated Depricated. Used getFullPriceInfo
     */
    function calculateCommission(price, auctionCommission, isFull) {
        var secondPercent = auctionSettingsData.vat,
            pricePercent = parseFloat(price) * parseFloat(auctionCommission / 100),
            varPercent = 0,
            vatRule = auctionSettingsData.houseCommissionVatRule;

        switch (vatRule) {
            case "EXEMPTED_FROM_VAT":
                varPercent = pricePercent;
                break;
            case "VAT_INCLUDED":
                varPercent = pricePercent + ((parseFloat(price) + pricePercent) * (secondPercent / 100));
                break;
            case "SHOULD_ADD_VAT":
                varPercent = pricePercent;
                //varPercent = pricePercent + (secondPercent / 100);
                // varPercent = pricePercent + (pricePercent * (secondPercent / 100));
                break;
            default:
                varPercent = pricePercent + (pricePercent * (secondPercent / 100));
        }

        if (isFull) {
            price = parseFloat(price) + (price * (secondPercent / 100));
            return (parseFloat(price) + varPercent).toFixed(2);
        } else {
            return (parseFloat(price) + varPercent).toFixed(2);
        }
    }

    function roundToCents(sum){
        return Math.round(sum*100)/100;
    }

    function getCommissonInfoForPrice(lot, auction, price) {
        var commission = price * (auction.commission) / 100;
        var commissionLabel = auction.commission+"%";
        if (auction.minimumItemCommission) {
            commissionLabel+=". Minimum commission: " + auction.currency+auction.minimumItemCommission;
            if (auction.itemPriceForMinimumCommission) {
                commissionLabel+=". Item price for minimum commission:"+auction.itemPriceForMinimumCommission;
                if (price <= auction.itemPriceForMinimumCommission) {
                    commission = auction.minimumItemCommission;
                }
            } else if (commission < auction.minimumItemCommission) {
                commission = auction.minimumItemCommission;
            }
        }
        return {
            commission:roundToCents(commission),
            commissionLabel:commissionLabel
        }
    }

    /**
     * currentItemInfo, auctionInfo, price
     * @param lot
     * @param auction
     * @param price
     * @returns {{hammerPrice, commissionInfo: {commission: *, commissionLabel: string}, vatInfo: {vat: *, vatLabel: string}, totalPriceInfo: {price: *, label: string}}}
     */
    function getFullPriceInfo(lot, auction, price) {
        let settings = bidspiritApi.getAuctionSettingsData(),
            vatPercent = settings.vat,
            shouldAddVat =  vatPercent  && (!bidspiritUser || !bidspiritUser.exemptedFromTax),
            commissionInfo = getCommissonInfoForPrice(lot, auction, price),
            priceWithCommission = roundToCents(price * 1+ commissionInfo.commission),
            totalPriceLabel,
            fullPriceVat = lot.fullPriceVat,
            vatLabel,
            vat;

        if (shouldAddVat) {
            vatLabel = vatPercent + "% " + bp_t("vat");
            if (commissionInfo.commission) {
                totalPriceLabel = bp_t("price_including_buyers_premium_and_vat");
                if (fullPriceVat) {
                    vatLabel += " " + bp_t("on_the_full_lots_price_and_commission");
                    if (settings.houseCommissionVatRule == 'SHOULD_ADD_VAT') {
                        vat = vatPercent * priceWithCommission / 100;
                    } else {
                        vat = vatPercent * price / 100;
                    }
                } else {
                    vatLabel += " " + bp_t("on commission only");
                    vat = vatPercent * commissionInfo.commission / 100;
                }
            } else {
                if (fullPriceVat) {
                    vatLabel = bp_t("on_item_price");
                    totalPriceLabel = bp_t("price_including_vat");
                    vat = vatPercent * price / 100;
                } else {
                    vatLabel = bp_t("exempted");
                    totalPriceLabel = bp_t("full_price_no_vat_or_buyers_permium");
                    vat = 0;
                }
            }
        } else {
            vatLabel = bp_t("exempted");
            totalPriceLabel = bp_t("total_with_commission");
            vat = 0;
        }
        vat = roundToCents(vat);
        return {
            hammerPrice: parseFloat(price),
            commissionInfo: commissionInfo,
            vatInfo:{
                vat:vat,
                vatLabel:vatLabel
            },
            totalPriceInfo:{
                price:roundToCents(priceWithCommission + vat),
                label:totalPriceLabel
            }

        }
    }

    function getCommissionPrice(price, fullPriceVat, auctionCommission) {
        if (fullPriceVat === undefined) {
            var singleLot = $("#single-lot");
        }

        if (fullPriceVat === undefined) {
            fullPriceVat = Boolean(parseInt(singleLot.attr("data-full-price-vat")));
        }

        if (auctionCommission === undefined) {
            auctionCommission = bidspiritApi.getAuctionInfo().commission;
        }

        return calculateCommission(price, auctionCommission, fullPriceVat);
    }

    function renderCommissionPrice(price) {
        let fullPriceInfo = getFullPriceInfo(currentItemInfo, auctionInfo, price),
            auctionHouseData = bidspiritApi.getAuctionSettingsData(),
            fullVatPrice = Boolean(parseInt($("#single-lot").attr("data-full-price-vat"))),
            secondaryFullPrice = 0,
            text = "";

        console.log(fullPriceInfo);

        if (auctionInfo.secondCurrencyRate !== undefined) {
            secondaryFullPrice = (fullPriceInfo.totalPriceInfo.price * (auctionInfo.secondCurrencyRate).toFixed(4)).toFixed(2);
            text = " (" + formattedPrice(secondaryFullPrice,auctionInfo.secondCurrency) + ")";
        }

        loadTemplate("#bp-fullPrice", "full-price-template", {
            text: text,
            fullPriceVat: fullVatPrice,
            fullPriceInfo: getFullPriceInfo(currentItemInfo, auctionInfo, price),
            auctionHouseData: auctionHouseData,
            currencySymbol: currencySymbol
        });
    }

    function galleryInitial() {
        function featureGallery(galleryMainSlider, galleryThumbs) {
            var bidspiritUser = bidspiritApi.getBidspiritUser(),
                galleryInfo = $("#gallery-info");

            if (window.bs_data.only_for_user_auth && bidspiritUser !== undefined) {
                var imageWrapper = $("#wrpLotImages");
                galleryInfo.remove();

                if (imageWrapper.length) {
                    var imageList = imageWrapper.attr("data-image-list"),
                        imageTemplate = imageWrapper.attr("data-image-template"),
                        imgTemplate = "",
                        isCloned = Boolean(parseInt(imageWrapper.attr("data-image-cloned")));

                    try {
                        imageTemplate = JSON.parse(imageTemplate);
                        imageList = imageList.split(/\,/);
                        imgTemplate = imageTemplate.uncloned.custom;

                        if (Array.isArray(imageList)) {
                            imageList.splice(0, 1);
                        }

                        if (isCloned) {
                            imgTemplate = imageTemplate.cloned.custom;
                        }

                        var mainSlide = [],
                            thumbSlide = [];
                        imageList.forEach(function (elem, index) {
                            var imgSrc = "";
                            imgSrc = imgTemplate.replace(/\$1/g, elem);
                            imgSrc = imgSrc.replace(/\$2/g, elem.replace(/\D+/, ""));
                            var thumbsTemplate = `<div data-slide="${index + 1}" class='grid-slide swiper-slide' style='background-image:url("${imgSrc}")'></div>`,
                                slideTemplate = `<a href="${imgSrc}" data-fancybox-bp="gallery" class="swiper-slide" style="background-image:url('${imgSrc}')"></a>`;
                            mainSlide.push(slideTemplate);
                            thumbSlide.push(thumbsTemplate);
                        });

                        if (mainSlide.length > 0) {
                            galleryMainSlider.appendSlide(mainSlide);

                            if (typeof galleryThumbs.appendSlide === "function") {
                                galleryThumbs.appendSlide(thumbSlide);
                            } else {
                                galleryThumbs.append(thumbSlide);
                            }
                        }
                    } catch (e) {
                        console.error(e);
                    }
                }
            } else {
                galleryInfo.removeClass(window.bs_data.hidden_class);
            }
        }

        var gallerySelector = ".bp-gallery-thumbs",
            topGallerySelector = ".bp-gallery-top",
            topGalleryConfig = {
                spaceBetween: 10,
                navigation: {
                    nextEl: ".swiper-button-next",
                    prevEl: ".swiper-button-prev"
                }
            },
            gridGalleryThumbs = ".bp-gallery-thumbs-grid",
            galleryMainSlider = null,
            galleryThumbs = null;

        if ($(gallerySelector).length) {
            galleryThumbs = new SwiperBP(".bp-gallery-thumbs", {
                spaceBetween: 10,
                slidesPerView: 4,
                freeMode: true,
                centeredSlidesBounds: true,
                slideToClickedSlide: true,
                watchSlidesVisibility: true,
                watchSlidesProgress: true
            });

            if ($(topGallerySelector).length) {
                topGalleryConfig.thumbs = {
                    swiper: galleryThumbs
                };
                galleryMainSlider = new SwiperBP(topGallerySelector, topGalleryConfig);
            }
        } else {
            if ($(topGallerySelector).length) {
                galleryMainSlider = new SwiperBP(topGallerySelector, topGalleryConfig), galleryThumbs = $(".bp-gallery-thumbs-grid .swiper-wrapper");

                if (gridGalleryThumbs.length) {
                    $(gridGalleryThumbs).on("click", ".swiper-slide", function (item) {
                        var slide = $(this).attr("data-slide");
                        galleryMainSlider.slideTo(slide);
                    });
                }
            }
        }

        $(window).on("bp:after-init", function (data) {
            featureGallery(galleryMainSlider, galleryThumbs);
        });
        $(window).on("bp:after-login", function (data) {
            featureGallery(galleryMainSlider, galleryThumbs);
        });
    }

    function initIncrementSteps(incrementsStepPrices, minPrice, enablePrebidsUnderStartPrice) {
        if (minPrice === undefined) {
            return;
        }

        allIncrementsPrices = [];
        var startStep = null,
            price = 0,
            bidLength = 200,
            bidCount = 0;

        if (enablePrebidsUnderStartPrice !== undefined && enablePrebidsUnderStartPrice === true) {
            allIncrementsPrices.push(1);
        }

        for (var j = 0; j < incrementsStepPrices.length; j++) {
            if (incrementsStepPrices[j][0] >= price) {
                if (incrementsStepPrices[j - 1] !== undefined) {
                    startStep = incrementsStepPrices[j - 1][0];
                    break;
                } else {
                    startStep = incrementsStepPrices[j][0];
                    break;
                }
            }
        }

        for (var i = 0; i < incrementsStepPrices.length; i++) {
            var increment = incrementsStepPrices[i],
                step = increment[1],
                nextPart = null;

            if (incrementsStepPrices[i + 1] !== undefined) {
                nextPart = incrementsStepPrices[i + 1][0];

                while (nextPart > price) {
                    price += step;

                    if (price > minPrice) {
                        allIncrementsPrices.push(price);
                        bidCount++;
                    }

                    if (bidLength === bidCount) {
                        return;
                    }
                }
            } else {
                while (bidLength >= bidCount) {
                    price += step;

                    if (price > minPrice) {
                        allIncrementsPrices.push(price);
                        bidCount++;
                    }
                }
            }
        }
    }

    /*function listIncrementSteps(incrementsStepPrices, minPrice) {
        if (incrementsStepPrices === null) {
            return [];
        }

        let incrementsPrices = [],
            price = 0,
            bidCount = 0;

        for (var i = 0; i < incrementsStepPrices.length; i++) {
            var increment = incrementsStepPrices[i],
                step = increment[1],
                nextPart = null;

            if (incrementsStepPrices[i + 1] !== undefined) {
                nextPart = incrementsStepPrices[i + 1][0];

                while (nextPart > price) {
                    price += step;
                    incrementsPrices.push(price);
                    bidCount++;
                }
            }
        }

        return incrementsPrices;
    }*/

    function select2ToolsInit() {
        function toolsInit(formTools) {
            var formSearch = $("#bp-from-tools .bp-btn-search"),
                inputSearch = formTools.find("[name=phrase_by]"),
                inputPerPage = formTools.find("[name=per_page]"),
                inputFilter = $(".bp-form_category"),
                soldFilter = $(".bp-form_sold-unsold"),
                btnClear = formTools.find(".bp-btn-close");
            var settingsSelect2 = {
                width: "resolve",
                theme: "default bp-custom-select",
                minimumResultsForSearch: -1,
                dropdownParent: $(".bp-form_sorter .bp-form-group__inner")
            };
            var settingsSelect2PerPage = {
                width: "resolve",
                theme: "default bp-custom-select",
                minimumResultsForSearch: -1,
                dropdownParent: $(".bp-form_per_page .bp-form-group__inner")
            };
            var settingsSelect2Category = {
                width: "resolve",
                theme: "default bp-custom-select",
                // minimumResultsForSearch: -1,
                dropdownParent: $(".bp-form_category .bp-form-group__inner"),
                placeholder: window.bs_lang.select_value,
                allowClear: true
            };

            if (formTools.length) {
                formSearch.on("click", ".bp-btn-search", function (event) {
                    event.preventDefault();
                    formTools.submit();
                });
                inputSearch.on("input, change", function (event) {
                    btnClear.removeClass(window.bs_data.hidden_class);
                });
                btnClear.on("click", function (event) {
                    event.preventDefault();
                    inputSearch.val("");
                    $(this).addClass(window.bs_data.hidden_class);
                    formTools.submit();
                });
                formSearch.on("submit", function (event) {
                    event.preventDefault();
                });
                var currentValue = inputSearch.val();

                if (currentValue !== "") {
                    inputSearch.trigger("change");
                }
            }

            var selectField = $(".bp-form_sorter .bp-filter-select2");

            if (formTools.length && selectField.length) {
                selectField.select2(settingsSelect2);
                selectField.on("select2:select", function (event) {
                    formTools.submit();
                });
            }

            if (inputFilter.length) {
                var selectFieldCategory = $(".bp-form_category .bp-filter-select2");
                selectFieldCategory.select2(settingsSelect2Category);
                selectFieldCategory.on("select2:clear", function (event) {
                    formTools.submit();
                });
                selectFieldCategory.on("select2:select", function (event) {
                    formTools.submit();
                });
            }

            if (formTools.length && inputPerPage.length) {
                var selectFieldPerPage = $(".bp-form_per_page .bp-per-page-select2");
                selectFieldPerPage.select2(settingsSelect2PerPage);
                selectFieldPerPage.on("select2:select", function (event) {
                    formTools.submit();
                });
            }

            if ($(".bp-day-switcher").length) {
                var daysSwitcher = $(".bp-day-switcher");
                daysSwitcher.select2({
                    width: "resolve",
                    theme: "default bp-custom-select",
                    minimumResultsForSearch: -1
                });
                daysSwitcher.on("select2:select", function (event) {
                    let data = event.params.data,
                        value = data.element.getAttribute("value");

                    if (value !== undefined) {
                        window.location = value;
                    }
                });
            }

            if (soldFilter.length) {
                soldFilter.find('.bp-select2').select2(settingsSelect2);
                soldFilter.on("select2:select", function (event) {
                    formTools.submit();
                });
            }
        }

        function toolsInitOutdated() {
            var formFilter = $("#bp-from-filter"),
                formSearch = $("#bp-from-search"),
                inputSearch = formSearch.find("[name=bp_auction_search]"),
                inputSearchHidden = $("#bp_auction_search"),
                inputFilter = $(".bp-form_category"),
                btnClear = formSearch.find(".bp-btn-close"),
                soldFilter = $(".bp-form_sold-unsold"),
                inputSorter = $(".bp-form_sorter");
            var settingsSelect2 = {
                width: "resolve",
                theme: "default bp-custom-select",
                minimumResultsForSearch: -1,
                dropdownParent: $(".bp-form_sorter .bp-form-group__inner")
            };
            var settingsSelect2Category = {
                width: "resolve",
                theme: "default bp-custom-select",
                minimumResultsForSearch: -1,
                dropdownParent: $(".bp-form_category .bp-form-group__inner"),
                placeholder: window.bs_lang.select_value,
                allowClear: true
            };

            if (formSearch.length) {
                formSearch.on("click", ".bp-btn-search", function (event) {
                    event.preventDefault();
                    formFilter.submit();
                });
                inputSearch.on("input, change", function (event) {
                    btnClear.removeClass(window.bs_data.hidden_class);
                });
                btnClear.on("click", function (event) {
                    event.preventDefault();
                    inputSearch.val("");
                    inputSearchHidden.val("");
                    $(this).addClass(window.bs_data.hidden_class);
                    formFilter.submit();
                });
                formSearch.on("submit", function (event) {
                    event.preventDefault();
                });
                inputSearch.on("keypress", function (event) {
                    if (event.keyCode === 13) {
                        inputSearchHidden.val(inputSearch.val());
                    }
                });
                var currentValue = inputSearch.val();

                if (currentValue !== "") {
                    inputSearch.trigger("change");
                }
            }

            if (inputSorter.length) {
                var selectField = $(".bp-form_sorter .bp-filter-select2"),
                    filterParam = searchGetParam("sort_by");
                selectField.select2(settingsSelect2);

                if (filterParam !== null) {
                    var select = selectField.find('option[value="' + filterParam + '"]');

                    if (select.length) {
                        selectField.val(filterParam);
                        selectField.trigger("change");
                    }
                }

                selectField.on("select2:select", function (event) {
                    formFilter.submit();
                });
            }

            if (inputSearch.length) {
                inputSearch.on("input, change", function (event) {
                    inputSearchHidden.val($(this).val());
                });
            }

            if (inputFilter.length) {
                var selectFieldCategory = $(".bp-form_category .bp-filter-select2"),
                    filterParamCategory = searchGetParam("category_by");
                selectFieldCategory.select2(settingsSelect2Category);

                if (filterParamCategory !== null) {
                    var selectCategory = selectFieldCategory.find('option[value="' + filterParamCategory + '"]');

                    if (selectCategory.length) {
                        selectFieldCategory.val(filterParamCategory);
                        selectFieldCategory.trigger("change");
                    }
                }

                selectFieldCategory.on("select2:clear", function (event) {
                    formFilter.submit();
                });
                selectFieldCategory.on("select2:select", function (event) {
                    formFilter.submit();
                });
            }
        }

        var formTools = $("#bp-from-tools");

        if (formTools.length > 0) {
            toolsInit(formTools);
        } else {
            toolsInitOutdated();
        }
    }

    function select2init() {
        function loadStepSelect() {
            (function (auctionInfo) {
                var select = $("#bidFormPrice"),
                    minBidPrice = 1,
                    enablePrebidsUnderStartPrice = false;

                if (auctionInfo.increments !== undefined) {
                    hangUpEvent("bp:get-increment-steps", auctionInfo.increments);
                }

                if (currentItemInfo !== null) {
                    var itemInfo = currentItemInfo,
                        settings = bidspiritApi.getAuctionSettingsData();
                    select.empty();


                    if (itemInfo.leadingBid !== undefined && itemInfo.leadingBid.isSelf && itemInfo.selfAbsenteeBid !== undefined && !isNaN(itemInfo.selfAbsenteeBid.price) && itemInfo.selfAbsenteeBid.price > 0) {
                        minBidPrice = itemInfo.selfAbsenteeBid.price - 1;
                    } else if (itemInfo.leadingBid !== undefined) {
                        minBidPrice = itemInfo.leadingBid.price;
                    } else if (settings.enablePrebidsUnderStartPrice !== undefined && settings.enablePrebidsUnderStartPrice === true) {
                        enablePrebidsUnderStartPrice = true;

                        if (auctionInfo.increments[0][0] !== undefined && auctionInfo.increments[0][0] > 0) {
                            minBidPrice = auctionInfo.increments[0][0] - 1;
                        } else {
                            minBidPrice = 0;
                        }
                    } else if (itemInfo.startPrice !== undefined) {
                        minBidPrice = itemInfo.startPrice;
                        select.append('<option value="' + minBidPrice + '">' + formattedPrice(minBidPrice, currencySymbol) + "</option>");
                    } else {
                        select.append('<option value="0">' + formattedPrice(0, currencySymbol) + "</option>");
                    }

                    if (isNaN(minBidPrice) || minBidPrice === undefined || minBidPrice === null) {
                        if (itemInfo.leadingBid !== undefined && !isNaN(itemInfo.leadingBid.price)) {
                            minBidPrice = itemInfo.leadingBid.price;
                        } else if (itemInfo.startPrice !== undefined && !isNaN(itemInfo.startPrice)) {
                            minBidPrice = itemInfo.startPrice;
                        } else {
                            minBidPrice = 0;
                        }
                    }

                    initIncrementSteps(bidspiritApi.getAuctionInfo().increments, minBidPrice);

                    for (var i = 0; i < allIncrementsPrices.length; i++) {
                        var stepPrice = allIncrementsPrices[i];

                        if (stepPrice !== undefined) {
                            select.append('<option value="' + stepPrice + '">' + formattedPrice(stepPrice, currencySymbol) + "</option>");
                        }
                    }
                }
            })(bidspiritApi.getAuctionInfo());
        }

        loadStepSelect();
        var settingsSelect2 = {
            width: "resolve",
            theme: "default bp-custom-select",
            minimumResultsForSearch: -1,
            templateSelection: function (data, container) {
                renderCommissionPrice(data.id);
                return data.text;
            }
        };
        $(".bp-select2").each(function (index, elem) {
            $(elem).select2(settingsSelect2).trigger("change");
        });
    }

    function select2build(elemId, items) {
        return $(elemId).select2({
            data: items,
            minimumResultsForSearch: -1,
            width: "resolve"
        });
    }

    function setInvitationsEnabled(value) {
        bidspiritQuery("users/setInvitationsEnabled", {
            sessionId: bidspiritSessionId,
            isEnabled: value
        });
    }

    function updateUserDisplay() {
        (function () {
            var userFront = $("#userFront");

            if (bidspiritUser && userFront.length) {
                loadTemplate("#modal-profile-content", "user-profile-form", bidspiritUser);
            }
        })();
    }

    function someCode() {
        var singleLogin = $(".bp-single-login-btn");

        if (singleLogin.length && bidspiritUser !== undefined) {
            singleLogin.addClass(window.bs_data.hidden_class);
        }

        if (bidspiritUser !== undefined) {
            $(".bp-register-api, .bp-login-api").each(function (index, elem) {
                if (elem.name === "bp_short_login_form" || elem.name === "bp_short_register_form") {
                    elem.innerHTML = '<div class="bs-loader-small"></div>';
                    window.location = window.bs_data.link_profile;
                } else {
                    elem.innerHTML = "<p class='bp-notice'>" + window.bs_lang.login_success_hello + ", " + bidspiritUser.firstName + "!</p>";
                }
            });
        }
    }

    function noticeUser(bidspiritUser) {
        var mainContentContainer = $(".bp-main-container");

        if (bidspiritUser !== undefined && bidspiritUser.approvalState !== null && bidspiritUser.approvalState !== "APPROVED" && mainContentContainer.length) {
            mainContentContainer.empty();
            loadTemplateInsert(mainContentContainer, "main-notice-template", {
                type: bidspiritUser.approvalState,
                emailConfirmed: bidspiritUser.emailConfirmed
            }, true, true, function () {
                resendEmailAction();
            });
        }
    }

    function renderVatField(auctionHouseData) {
        var fullVatPrice = Boolean(parseInt($("#single-lot").attr("data-full-price-vat")));

        if (auctionHouseData.noVatOnCommission && !fullVatPrice) {
            $(".vat-field").remove();
        } else if (auctionHouseData.noVatOnCommission && fullVatPrice) {
            $(".vat-field span").html(window.bs_lang.vat_lot_price_commission);
        }
    }

    /**
     * Checks for unpaid invoices and shows a site-wide banner.
     * Uses server-side WordPress transients to avoid API calls on every page load.
     * Called once from initCore() when a user is logged in.
     *
     * Session logic:
     *  - First page load of a browser session (or after login): always fetches fresh from BidSpirit API.
     *  - Subsequent page loads in the same session: uses the server-side cache.
     *  - If the user clicked "Pay Now" (banner or individual bill): banner is suppressed for this session.
     */
    function checkUnpaidBillsBanner() {
        if (!bidspiritUser || !bidspiritUser.email) return;
        var userKey = bidspiritUser.email;

        try {
            // First page load of a session (or right after login): bypass cache, fetch fresh
            if (!sessionStorage.getItem("af_bills_session_checked")) {
                fetchAndCacheUnpaidBills(userKey);
                return;
            }
        } catch(e) {}

        // Subsequent page loads: check server-side cache first
        $.ajax({
            type: "post",
            dataType: "json",
            url: window.wp_data.ajax_url,
            data: {
                action: "af_get_unpaid_status",
                security: window.wp_nonce,
                user_key: userKey
            }
        }).done(function(res) {
            if (res.success && res.data.cached) {
                // Cache hit — use stored status, no BidSpirit API call
                if (res.data.has_unpaid) {
                    renderUnpaidBanner(res.data.count);
                }
                return;
            }
            // Cache miss — fetch from BidSpirit API
            fetchAndCacheUnpaidBills(userKey);
        }).fail(function() {
            // WP AJAX failed — try BidSpirit directly as fallback
            fetchAndCacheUnpaidBills(userKey);
        });
    }

    /**
     * Fetches unpaid bills from BidSpirit and stores result in server-side cache.
     * Sets a sessionStorage flag so subsequent page loads in the same session use the cache.
     */
    function fetchAndCacheUnpaidBills(userKey) {
        bidspiritQuery("bills/getUnpaidBills", {
            sessionId: bidspiritSessionId,
            language: LANG
        }, function (data) {
            var bills = data && data.response ? data.response : [];
            if (!Array.isArray(bills)) bills = [];
            var count = bills.length;

            // Mark this session as checked so subsequent page loads use the cache
            try { sessionStorage.setItem("af_bills_session_checked", "1"); } catch(e) {}

            // Store in server-side cache
            $.ajax({
                type: "post",
                url: window.wp_data.ajax_url,
                data: {
                    action: "af_set_unpaid_status",
                    security: window.wp_nonce,
                    user_key: userKey,
                    count: count
                }
            });

            if (count > 0) {
                renderUnpaidBanner(count);
            }
        }, function () {
            // BidSpirit API failed — don't show banner
        });
    }

    /**
     * Clears the server-side unpaid bills cache for the current user.
     */
    function clearUnpaidBillsCache() {
        if (!bidspiritUser || !bidspiritUser.email) return;
        $.ajax({
            type: "post",
            url: window.wp_data.ajax_url,
            data: {
                action: "af_set_unpaid_status",
                security: window.wp_nonce,
                user_key: bidspiritUser.email,
                clear: "1"
            }
        });
    }

    /**
     * Renders (or removes) the unpaid invoice alert banner.
     */
    function renderUnpaidBanner(count) {
        // Remove any existing banner first
        $(".bp-unpaid-invoice-banner").remove();

        if (!count || count <= 0) return;

        var profileUrl = (window.bs_data && window.bs_data.link_profile)
            ? window.bs_data.link_profile + "#bp-bills"
            : "#bp-bills";

        var bannerHtml = '<div class="bp-unpaid-invoice-banner" style="' +
            'width: 100%; z-index: 999; ' +
            'background: #cc0000; ' +
            'color: #fff; text-align: center; padding: 10px 20px; ' +
            'font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, sans-serif; ' +
            'display: flex; align-items: center; justify-content: center; gap: 15px;">' +
            '<span style="font-weight: 700;">⚠ This account has open invoices</span>' +
            '<a href="' + profileUrl + '" class="bp-unpaid-pay-btn" style="' +
            'display: inline-block; background: #fff; color: #000; ' +
            'padding: 5px 20px; border-radius: 50px; text-decoration: none; ' +
            'font-weight: 700; font-size: 13px; ' +
            'transition: background 0.2s ease; border: none; cursor: pointer;"' +
            ' onmouseover="this.style.background=\'#e6e6e6\'" onmouseout="this.style.background=\'#fff\'"' +
            '>Pay Now</a>' +
            '</div>';

        // Insert after the site header
        var $header = $("header.elementor-location-header, #masthead, header").first();
        if ($header.length) {
            $header.after(bannerHtml);
        } else {
            $("body").prepend(bannerHtml);
        }

        // Clear cache and remove banner; next page load will do a fresh check
        $(".bp-unpaid-pay-btn").on("click", function(e) {
            clearUnpaidBillsCache();
            try { sessionStorage.removeItem("af_bills_session_checked"); } catch(e2) {}

            // If we're already on the profile page, activate the tab directly
            var billsTab = $('.bp-tabs-block a[href="#bp-bills"]');
            if (billsTab.length) {
                e.preventDefault();
                // Set hash — the hashchange listener will handle the tab switch + scroll
                window.location.hash = "#bp-bills";
                // Remove the banner
                $(".bp-unpaid-invoice-banner").remove();
            }
        });
    }

    /**
     * Watches for clicks on individual invoice "Pay Now" / "Resume" buttons
     * in the My Invoices tab. Clears the server-side unpaid cache so the
     * banner re-evaluates on the next page load.
     */
    $(document).on("click", "#profile-bills-section a.bp-btn", function() {
        var href = $(this).attr("href") || "";
        // Only act on payment links (Pay Now / Resume), not View or Download PDF
        if (href.indexOf("standaloneScene=payment") !== -1 || href.indexOf("paymentUrl") !== -1) {
            clearUnpaidBillsCache();
            try { sessionStorage.removeItem("af_bills_session_checked"); } catch(e) {}
            // Remove the banner immediately since user is taking action
            $(".bp-unpaid-invoice-banner").remove();
        }
    });

    function initApp() {
        var firebaseTokenFCM = getCookie("FCM_TOKEN");

        if (firebaseTokenFCM !== "") {
            try {
                localStorage.setItem("token_firebase_push_id", firebaseTokenFCM);
            } catch (e) {
                console.error("Local storage disabled");
            }
        }
    }
    
    function init() {
        $("#bsLoader").removeClass(window.bs_data.hidden_class);
        bidspiritApi.setBidspiritSessionId();
        bidspiritQuery("users/initSession", {
            sessionId: bidspiritApi.getBidspiritSessionId(),
            language: LANG
        }, function (data) {
            let coreData = data;
            if (data.response !== undefined) {
                function initCore(data) {
                    updateUserDisplay();
                    updateDisplay();
                    loginLink();
                    someCode();

                    galleryInitial();
                    updateLotsWidget();
                    updateWidgetLots();
                    widgetSliders();

                    hangUpEvent("bp:after-init", data.response);
                    checkPoint("bp-init");

                    if (bidspiritUser !== undefined) {
                        checkPoint("bp-login");

                        if (bidspiritUser.approvalState !== undefined && bidspiritUser.approvalState === "APPROVED") {
                            checkPoint("bp-approved-user");
                        }

                        // Check for unpaid invoices (uses server-side cache)
                        checkUnpaidBillsBanner();
                    }
                }

                if (data.response.user !== undefined) {
                    bidspiritApi.setAuthToken(data.response.user.authToken);
                }

                try {
                    bidspiritSessionId = localStorage.bidspiritSessionId = data.response.sessionId;
                } catch (e) {
                    console.error("Local storage disabled");
                    bidspiritSessionId = "";
                }

                bidspiritQuery("settings/getHouseInfo", {
                    sessionId: bidspiritSessionId,
                    language: LANG
                }, function (data) {
                    auctionHouseData = data.response;
                    bidspiritApi.setAuctionHouseData(auctionHouseData);
                });

                bidspiritApi.setBidspiritUser(data.response.user);

                bidspiritQuery("settings/getSettings", {
                    sessionId: bidspiritSessionId,
                    language: LANG
                }, function (data) {
                    auctionSettingsData = data.response;
                    bidspiritApi.setAuctionSettingsData(auctionSettingsData);

                    initCore(coreData);
                });
            }

            bidspiritQuery("settings/getCountriesList", {
                sessionId: bidspiritSessionId,
                language: LANG
            }, function (data) {
                countriesList = data.response;
                bidspiritApi.setCountriesList(countriesList);

                (function () {
                    let codeSelect = jQuery('.countryCodeField'),
                        countriesList = bidspiritApi.getCountriesList(),
                        codeItems = jQuery.map(countriesList, function (obj) {
                            if (obj.phoneCode !== undefined) {
                                return {
                                    id: obj.phoneCode,
                                    text: obj.phoneCode + " (" + obj.name + ")"
                                };
                            }
                        });
                    codeSelect.each(function (index, elem) {
                        if (elem.classList.contains(window.bs_data.hidden_class)) {
                            elem.classList.remove(window.bs_data.hidden_class);
                        }

                        if (!!jQuery(elem).select2) {
                            jQuery(elem).select2({
                                theme: "default bp-custom-select",
                                width: "resolve",
                                data: codeItems,
                                placeholder: window.bs_lang.country_code
                            });
                        }
                    })
                })();
            });

            passwordShowAction();
        }, function (data) {
            disableLoader();
        });
    }

    function loadBid(lotIndex, currentAuctionNumber) {
        function vatAndCommission() {
            if (!!document.getElementById('vat-and-commission')) {
                let itemInfo = bidspiritApi.getAuctionItemInfo(),
                    auctionInfo = bidspiritApi.getAuctionInfo();
                if (itemInfo.item !== undefined) {
                    loadTemplate('#vat-and-commission', 'vat-and-commission-template', {
                        itemInfo: itemInfo,
                        fullPriceInfo: getFullPriceInfo(itemInfo, auctionInfo, 1),
                        auctionHouseData: bidspiritApi.getAuctionSettingsData(),//bidspiritApi.getAuctionHouseData() - some fields depricated
                        settings: bidspiritApi.getAuctionSettingsData(),
                        bidspiritUser: bidspiritUser,
                    })
                }
            }
        }

        if (currentAuctionNumber === "") {
            return;
        }

        bidspiritQuery("items/getAuctionItem", {
            sessionId: bidspiritSessionId,
            auctionId: currentAuctionNumber,
            itemIndex: lotIndex,
            language: LANG
        }, function (data) {
            String.prototype.allReplace = function (obj) {
                var retStr = this;

                for (var x in obj) {
                    retStr = retStr.replace(new RegExp("\\" + x, "g"), obj[x]);
                }

                return retStr;
            }; //oversea

            bidspiritApi.setAuctionItemInfo(data.response);

            if (data.response !== undefined) {
                hangUpEvent("bp:get-auction-item", data.response);
            }

            vatAndCommission();

            if ($('#startPriceSingleLot').length > 0) {
                if (data.response.item.startPrice !== undefined && data.response.item.currency !== undefined) {
                    $('#startPriceSingleLot').html(formattedPrice(data.response.item.startPrice, data.response.item.currency, true));
                }
            }

            bidspiritQuery("items/getItemsInfo", {
                sessionId: bidspiritSessionId,
                auctionId: currentAuctionNumber,
                lotIndexes: lotIndex
            }, function (data) {
                if (!checkError(data)) {
                    if (data.response !== undefined) {
                        hangUpEvent("bp:get-items-info", data.response);
                    }

                    if (data.response.notFoundLots[0] === lotIndex) {
                        console.error("error", "Lot " + lotIndex, window.bs_lang.not_found);
                        disableLoader();
                    } else {
                        currentItemInfoResponse = data.response;
                        currentItemInfo = data.response.itemsInfo[lotIndex];

                        if (bpIsset(currentItemInfo)) {
                            if (bpIsset(currentItemInfo.isFavorite) && currentItemInfo.isFavorite) {
                                $("#single-lot").find(".bp__wishlist").addClass("bp__wishlist-active");
                            }

                            displayBidFormData(currentItemInfo);
                            buyoutAction(currentItemInfoResponse, lotIndex, currentAuctionNumber);
                            postSaleAction(currentItemInfoResponse, lotIndex, currentAuctionNumber);
                            renderVatField(auctionHouseData);
                            hangUpEvent("bp:after-getItemsInfo-content-item", currentItemInfo, $("#single-lot"));
                        } else {
                            noticeSwall("info", window.bs_lang.not_found);
                            disableLoader();
                        }
                    }
                } else {
                    disableLoader();
                }
            });
        });
    }

    function buyoutAction(currentItemInfoResponse, lotIndex, auctionNumber) {
        var currentItemInfo = currentItemInfoResponse.itemsInfo[lotIndex],
            preSaleSectionSelector = "#preSale-section",
            auctionCommission = bidspiritApi.getAuctionInfo().commission,
            modalPreSaleForm = "#modal-pre-sale-content",
            auctionItemInfo = bidspiritApi.getAuctionItemInfo(),
            fullPriceVat = auctionItemInfo.item.fullPriceVat,
            isShop = Boolean(parseInt($(preSaleSectionSelector).attr("data-is-shop")));

        if (currentItemInfoResponse.state === "ENDED" || currentItemInfoResponse.state === "ARCHIVED") {
            return;
        }

        if (currentItemInfoResponse.auctionIsLive === true || currentItemInfo.buyoutPrice === undefined) {
            return;
        }

        if (currentItemInfo.leadingBid !== undefined && currentItemInfo.leadingBid.price !== undefined && currentItemInfo.leadingBid.price >= currentItemInfo.buyoutPrice) {
            return;
        }

        if (currentItemInfo.soldBid !== undefined && currentItemInfo.soldBid.price !== undefined) {
            return;
        }

        $(modalPreSaleForm).off("click", "#agreeSaleBid").on("click", "#agreeSaleBid", function (event) {
            event.preventDefault();
            let $this = $(this);
            $this.prop("disabled", true);
            $this.addClass("bp-disabled");
            bidspiritPostQuery("items/buyout", {
                sessionId: bidspiritSessionId,
                auctionId: auctionNumber,
                lotIndex: lotIndex,
                price: currentItemInfo.buyoutPrice
            }, function (data) {
                if (!checkError(data)) {
                    if (data.response.success === true) {
                        MicroModal.close("modal-pre-sale");
                        $(modalPreSaleForm).empty();
                        $(preSaleSectionSelector).empty();
                        loadTemplate(modalPreSaleForm, "modal-presale-confirm-template", {
                            data: auctionHouseData
                        }, false, function () {
                            MicroModal.show("modal-pre-sale", microModalInitConfig());
                        });
                        loadBid(lotIndex, auctionNumber);
                        afLogIP("bid", bidspiritUser);
                    }
                } else {
                    MicroModal.close("modal-pre-sale");
                    noticeSwall("info", data.response.errorMessage);
                    $(preSaleSectionSelector).empty();
                }
            }, function () {
            }, function () {
                $this.prop("disabled", false);
                $this.removeClass("bp-disabled");
            });
        });

        if (currentItemInfo.buyoutPrice > 0 && currentItemInfo.buyoutPrice >= currentItemInfo.startPrice) {
            var commissionPrice = calculateCommission(currentItemInfo.buyoutPrice, auctionCommission, fullPriceVat);
            loadTemplate(preSaleSectionSelector, "pre-sale-template", {
                currentItemInfo: currentItemInfo,
                currentCurrency: currencySymbol,
                price: currentItemInfo.buyoutPrice,
                commissionPrice: commissionPrice,
                isShop: isShop
            }, true, function () {
                $(preSaleSectionSelector).on("click", "#pre-sale-action", function (event) {
                    event.preventDefault();

                    if (!bidspiritUser) {
                        try {
                            MicroModal.show("modal-login", microModalInitConfig());
                        } catch (e) {
                            console.error(e);
                        }

                        return;
                    }

                    var lotName = $(modalPreSaleForm).attr("data-name"),
                        lotLinkTerm = window.bs_data.page_terms;
                    MicroModal.show("modal-pre-sale", microModalInitConfig());
                    loadTemplate(modalPreSaleForm, "modal-presale-template", {
                        index: currentItemInfo.lotIndex,
                        name: lotName,
                        currentCurrency: currencySymbol,
                        price: currentItemInfo.buyoutPrice,
                        linkTerms: lotLinkTerm,
                        commissionPrice: commissionPrice,
                        buyoutAction: true,
                        auctionCommission: auctionCommission,
                        auctionHouseData: auctionHouseData,
                        fullPriceVat: fullPriceVat
                    }, false, function () {
                        $(modalPreSaleForm).on("click", "#dontAgreeSaleBid", function (event) {
                            event.preventDefault();
                            MicroModal.close("modal-pre-sale");
                        });
                    });
                });
            });
        } else {
            console.info("not for pre sold");
        }
    }

    function postSaleAction(currentItemInfoResponse, lotIndex, currentAuctionNumber) {
        var currentItemInfo = currentItemInfoResponse.itemsInfo[lotIndex],
            postSaleSectionSelector = "#postSaleBid",
            auctionInfo = bidspiritApi.getAuctionInfo(),
            //houseInfo = bidspiritApi.getAuctionHouseData(),
            auctionCommission = auctionInfo.commission,
            auctionItemInfo = bidspiritApi.getAuctionItemInfo(),
            fullPriceVat = auctionItemInfo.item.fullPriceVat,
            //postAuctionSaleOpenedUntil = Boolean(parseInt($(postSaleSectionSelector).attr("data-post-auction-sale-opened-until"))),
            wrpNotice = $(postSaleSectionSelector).parents(".bp-control__notice"),
            modalPostSaleForm = "#modal-post-sale-content",
            commissionPrice = calculateCommission(currentItemInfo.postSalePrice, auctionCommission, fullPriceVat),
            timestamp = new Date().getTime();

        let [currentAuctionDayIndex, postAuctionSaleOpenedUntil] = initialPostAuctionSaleOpenedUntil(auctionInfo, lotIndex);

        // Available and for first day with post sale enabled
        /*if (currentItemInfoResponse.state !== "ENDED" && currentItemInfoResponse.state !== "ARCHIVED") {
            return;
        }*/

        if (!postAuctionSaleOpenedUntil) {
            //console.log("testX2", auctionInfo, !postAuctionSaleOpenedUntil, postAuctionSaleOpenedUntil);
            return;
        }

        if (currentItemInfo.soldBid !== undefined && currentItemInfo.soldBid.price !== undefined) {
            //console.log("testX33", auctionInfo, currentItemInfo, (currentItemInfo.soldBid !== undefined && currentItemInfo.soldBid.price !== undefined));
            return;
        }

        addBodyClass("bp_sale_action");
        $(modalPostSaleForm).off("click", "#agreeSaleBid").on("click", "#agreeSaleBid", function (event) {
            event.preventDefault();
            let $this = $(this);
            $this.prop("disabled", true);
            $this.addClass("bp-disabled");
            bidspiritPostQuery("items/postSalePurchase", {
                sessionId: bidspiritSessionId,
                auctionId: currentAuctionNumber,
                lotIndex: lotIndex,
                price: currentItemInfo.postSalePrice
            }, function (data) {
                if (!checkError(data)) {
                    if (data.response.success === true) {
                        MicroModal.close("modal-pre-sale");
                        $(postSaleSectionSelector).empty();
                        $(modalPostSaleForm).empty();
                        loadTemplate(modalPostSaleForm, "modal-post-sale-confirm-template", {
                            data: auctionHouseData
                        }, false, function () {
                            MicroModal.show("modal-post-sale", microModalInitConfig());
                        });
                        loadBid(lotIndex, currentAuctionNumber);
                        afLogIP("bid", bidspiritUser);
                    }
                } else {
                    MicroModal.close("modal-post-sale");
                    noticeSwall("info", data.response.errorMessage);
                    $(modalPostSaleForm).empty();
                }
            }, function () {
            }, function () {
                $this.prop("disabled", false);
                $this.removeClass("bp-disabled");
            });
        });

        //currentItemInfo.wasInLiveAuction
        //console.log("testX5", currentItemInfo, postAuctionSaleOpenedUntil > timestamp);
        if ((currentItemInfo.wasInLiveAuction === true) && postAuctionSaleOpenedUntil > timestamp) {
            wrpNotice.addClass("bp-control__notice-mod");
            loadTemplate(postSaleSectionSelector, "post-sale-template", {
                currentItemInfo: currentItemInfo,
                currentCurrency: currencySymbol,
                price: currentItemInfo.postSalePrice
            }, true, function () {
                $(postSaleSectionSelector).on("click", "#post-sale-action", function (event) {
                    var lotName = $(modalPostSaleForm).attr("data-name"),
                        lotLinkTerm = window.bs_data.page_terms;

                    if (!bidspiritUser) {
                        try {
                            MicroModal.show("modal-login", microModalInitConfig());
                        } catch (e) {
                            console.error(e);
                        }

                        return;
                    }

                    MicroModal.show("modal-post-sale", microModalInitConfig());
                    loadTemplate(modalPostSaleForm, "modal-post-sale-template", {
                        index: currentItemInfo.lotIndex,
                        name: lotName,
                        currentCurrency: currencySymbol,
                        price: currentItemInfo.postSalePrice,
                        linkTerms: lotLinkTerm,
                        commissionPrice: commissionPrice,
                        buyoutAction: false,
                        auctionHouseData: auctionHouseData,
                        auctionCommission: auctionCommission,
                        fullPriceVat: fullPriceVat
                    }, false, function () {
                        $(modalPostSaleForm).on("click", "#dontAgreeSaleBid", function (event) {
                            event.preventDefault();
                            MicroModal.close("modal-post-sale");
                        });
                    });
                });
            });
        }

        hangUpEvent("bp:auction-sales", {
            currentItemInfoResponse,
            lotIndex,
            currentAuctionNumber
        });
    }

    function displayBidFormData(itemInfo) {
        currentItemInfo = itemInfo;
        let houseInfo = bidspiritApi.getAuctionHouseData(),
            settings = bidspiritApi.getAuctionSettingsData(),
            auctionItemInfo = currentItemInfoResponse["itemsInfo"][currentLotIndex],
            timestamp = new Date().getTime();

        let auctionInfo = bidspiritApi.getAuctionInfo(),
            lotIndex = auctionItemInfo.lotIndex;

        let [currentAuctionDayIndex, postAuctionSaleOpenedUntil] = initialPostAuctionSaleOpenedUntil(auctionInfo, lotIndex);

        function price(itemInfo) {
            var obj = {
                price: itemInfo.startPrice,
                leader: false
            };

            if (itemInfo["selfAbsenteeBid"] !== undefined && itemInfo["leadingBid"] !== undefined) {
                if (itemInfo["selfAbsenteeBid"].price && itemInfo["leadingBid"].isSelf) {
                    obj.price = itemInfo["selfAbsenteeBid"].price;
                    obj.leader = true;
                } else if (itemInfo["selfAbsenteeBid"].price) {
                    obj.price = itemInfo["selfAbsenteeBid"].price;
                } else {
                    obj.price = itemInfo["leadingBid"].price;
                }
            } else if (itemInfo["leadingBid"] !== undefined) {
                obj.price = itemInfo["leadingBid"].price;
            }

            return obj;
        }

        var visible = false,
            priceData = price(itemInfo);

        if (currentItemInfoResponse.state === "ENDED" || currentItemInfoResponse.state === "ARCHIVED" || currentItemInfoResponse.state === "READY") {
            visible = true;
        }

        if (auctionItemInfo.leadingBid !== undefined || auctionItemInfo.soldBid !== undefined) {
            visible = true;
        }

        if (auctionItemInfo.selfAbsenteeBid !== undefined && auctionItemInfo.selfAbsenteeBid.price !== undefined) {
            visible = true;
        }

        var singleLotSection = $("#single-lot"),
            hiddenPrice = false;

        if (singleLotSection !== undefined) {
            hiddenPrice = Boolean(parseInt(singleLotSection.attr("data-hidden-price")));
        }
        console.log("testX4", auctionInfo, currentAuctionDayIndex, auctionInfo.days[currentAuctionDayIndex], visible, postAuctionSaleOpenedUntil);
        loadTemplate("#leadingBid", "leadingBid-template", {
            currencySymbol: currencySymbol,
            item: auctionItemInfo,
            itemInfo: currentItemInfoResponse,
            postAuctionSaleOpenedUntil: postAuctionSaleOpenedUntil,
            postAuctionSaleOpened: (postAuctionSaleOpenedUntil > timestamp),
            obj: priceData,
            hiddenPrice: hiddenPrice,
            settings: settings,
            hideleadingBidSection: (auctionInfo.days[currentAuctionDayIndex] !== undefined && auctionInfo.days[currentAuctionDayIndex].auctionEnded === undefined)
        }, visible);
        loadTemplate("#houseInfo-section", "house-info-template", {
            auctionHouseData: bidspiritApi.getAuctionHouseData()
        }, visible);

        if (
            auctionItemInfo.wasInLiveAuction !== undefined &&
            auctionItemInfo.wasInLiveAuction === false &&
            auctionItemInfo.soldBid === undefined &&
            auctionInfo.absenteeBidsEnabled !== undefined &&
            auctionInfo.absenteeBidsEnabled === true
        ) {
            auctionIsLive(currentItemInfoResponse, auctionItemInfo);
        } else if (
            auctionItemInfo.startPrice === 0 &&
            settings.enablePrebidsUnderStartPrice !== undefined &&
            settings.enablePrebidsUnderStartPrice === false
        ) {
            if (!getCookie("bs_read_notice") && !isDisabledReadNotice()) {
                noticeSwall("warning", window.bs_lang.auction_preview_title, window.bs_lang.auction_preview_notice, {}, function () {
                    setCookie("bs_read_notice", true, 7);
                });
            }
        } else {
            console.info("auctionIsLive", auctionInfo, auctionItemInfo);
        }

        // Bid count fallback: adjust displayed count based on BidSpirit leading bid vs start price
        (function() {
            var $bidEl = $("#af-bid-count-display");
            if (!$bidEl.length) return;
            var startPrice = parseFloat(auctionItemInfo.startPrice) || 0;
            var leadingBidPrice = 0;
            if (auctionItemInfo.leadingBid !== undefined && auctionItemInfo.leadingBid.price !== undefined) {
                leadingBidPrice = parseFloat(auctionItemInfo.leadingBid.price) || 0;
            } else if (auctionItemInfo.selfAbsenteeBid !== undefined && auctionItemInfo.selfAbsenteeBid.price !== undefined) {
                leadingBidPrice = parseFloat(auctionItemInfo.selfAbsenteeBid.price) || 0;
            }
            if (leadingBidPrice > 0) {
                var svg = $bidEl.find("svg").prop("outerHTML") || "";
                var currentText = $bidEl.text().trim();
                var currentCount = parseInt(currentText) || 0;
                var minCount = 1;
                if (leadingBidPrice > startPrice && startPrice > 0) {
                    minCount = 2;
                }
                if (currentCount < minCount) {
                    $bidEl.html(svg + minCount + " " + (minCount === 1 ? "bid" : "bids"));
                }
            }
        })();

        disableLoader();
    }

    function auctionIsLive(dataResponse, item) {
        loadTemplate("#auctionIsLive-section", "auctionIsLive-template", {
            isLive: dataResponse.auctionIsLive,
            auctionInfo: bidspiritApi.getAuctionInfo(),
            linkLive: bidspiritApi.getLinkOnLive(),
            state: dataResponse.state,
            fullPriceInfo: getFullPriceInfo(currentItemInfo, auctionInfo, 1),
            auctionHouseData: bidspiritApi.getAuctionHouseData(),
            item: item
        });

        function checkShowcaseEnable(showcaseEnable) {
            if ($("#dateTimeField").length) {
                let dateTimeField = $("#dateTimeField"),
                    timeBegin = dateTimeField.attr("data-time"),
                    dateStart = timeShift(new Date(Date.parse(timeBegin))),
                    dateNow = new Date(),
                    timeToStart = (dateStart - dateNow) / 1000 / 3600;
                showcaseEnable = Boolean(parseInt(dateTimeField.attr("data-showcase-enable")));

                if (parseInt(timeToStart) < parseInt(window.bs_data.auto_close_showcase)) {
                    showcaseEnable = false;
                }
            }

            return showcaseEnable;
        }

        let showcaseEnable = window.bs_data.is_showcase_enable;

        if (checkShowcaseEnable(showcaseEnable)) {
            let showcase = $("#showcase-section");
            showcase.removeClass(window.bs_data.hidden_class);
        }

        if (dataResponse.state === "PRE_AUCTION") {
            disableLoader();
        }

        select2init();

        if (dataResponse !== undefined) {
            hangUpEvent("bp:auction-is-live", dataResponse);
        }

        $("#bp-showcase").on("click", function (event) {
            event.preventDefault();

            if (!checkShowcaseEnable(showcaseEnable)) {
                return;
            }

            let $this = $(this),
                title = $("#single-lot h1").text(),
                skuCode = $("#single-lot").attr("data-lot-index");
            $this.addClass(window.bs_data.loader_class);
            $.ajax({
                url: window.wp_data.ajax_url,
                type: "POST",
                dataType: "json",
                data: {
                    action: "do_showcase",
                    security: window.wp_nonce,
                    skuCode: skuCode
                }
            }).done(function (response) {
                if (response.success) {
                    noticeSwall("success", window.bs_lang.showcase_success_title.replace(/#title#/, title), window.bs_lang.showcase_success_notice, {}, function () {
                        if (response.data !== undefined && response.data.cart_url !== undefined) {
                            window.location = response.data.cart_url;
                        }
                    });
                } else {
                    noticeSwall("error", "", response.data.notice);
                }
            }).fail(function () {
                noticeSwall("error", window.bs_lang.error);
            }).always(function () {
                $this.prop("disabled", true);
                $this.removeClass(window.bs_data.loader_class);
            });
        });
    }

    function getDataForm(id) {
        var dataForm = {},
            form = document.forms[id];

        if (document.forms[id] !== undefined) {
            Array.prototype.forEach.call(form.elements, function (elem, index) {
                if (!elem.disabled) {
                    if (elem.type === "checkbox" || elem.type === "radio") {
                        dataForm[elem.name] = elem.checked.toString();
                    } else {
                        dataForm[elem.name] = elem.value;
                    }
                }
            });
        }

        return dataForm;
    }


    // AuctionForge User Tracking - Device ID + Browser Fingerprint (Tier 1)
    function afGetDeviceId() {
        var key = 'af_device_id';
        var id = null;
        try { id = localStorage.getItem(key); } catch(e) {}
        if (!id) {
            id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                var r = Math.random() * 16 | 0;
                return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
            });
            try { localStorage.setItem(key, id); } catch(e) {}
        }
        return id;
    }

    // Tier 1: High-entropy browser fingerprint
    var _afFingerprintCache = null;
    var _afAdvancedMetrics = {};

    // DJB2 hash helper
    function _afDjb2(str) {
        var hash = 5381;
        for (var i = 0; i < str.length; i++) {
            hash = ((hash << 5) + hash + str.charCodeAt(i)) & 0xFFFFFFFF;
        }
        return (hash >>> 0).toString(16);
    }

    // Async metrics that resolve after initial call
    var _afAsyncReady = false;
    var _afAsyncMetrics = { audio_hash: '', webrtc_ips: '', battery_info: '', voices_hash: '', media_devices: '' };

    // Kick off async collectors immediately on page load
    (function _afInitAsync() {
        // 1. AudioContext fingerprint (async — renders in background)
        try {
            var AudioCtx = window.OfflineAudioContext || window.webkitOfflineAudioContext;
            if (AudioCtx) {
                var actx = new AudioCtx(1, 44100, 44100);
                var osc = actx.createOscillator();
                osc.type = 'triangle';
                osc.frequency.setValueAtTime(10000, actx.currentTime);
                var comp = actx.createDynamicsCompressor();
                comp.threshold.setValueAtTime(-50, actx.currentTime);
                comp.knee.setValueAtTime(40, actx.currentTime);
                comp.ratio.setValueAtTime(12, actx.currentTime);
                comp.attack.setValueAtTime(0, actx.currentTime);
                comp.release.setValueAtTime(0.25, actx.currentTime);
                osc.connect(comp);
                comp.connect(actx.destination);
                osc.start(0);
                actx.startRendering();
                actx.oncomplete = function(ev) {
                    try {
                        var buf = ev.renderedBuffer.getChannelData(0);
                        var sum = 0;
                        for (var i = 4500; i < 5000; i++) sum += Math.abs(buf[i]);
                        _afAsyncMetrics.audio_hash = 'au_' + _afDjb2(sum.toString());
                        _afFingerprintCache = null; // force recalc
                    } catch(e) {}
                };
            }
        } catch(e) {}

        // 2. WebRTC Local IP discovery
        try {
            var pc = new (window.RTCPeerConnection || window.webkitRTCPeerConnection)({iceServers: []});
            var ips = [];
            pc.createDataChannel('');
            pc.createOffer().then(function(sdp) {
                pc.setLocalDescription(sdp);
            }).catch(function(){});
            pc.onicecandidate = function(ev) {
                if (!ev || !ev.candidate) {
                    _afAsyncMetrics.webrtc_ips = ips.join(',');
                    try { pc.close(); } catch(e) {}
                    return;
                }
                var parts = ev.candidate.candidate.split(' ');
                if (parts.length >= 5) {
                    var ip = parts[4];
                    if (ip && ip.indexOf('.') !== -1 && ips.indexOf(ip) === -1) ips.push(ip);
                }
            };
            setTimeout(function() {
                try { pc.close(); } catch(e) {}
                if (ips.length) _afAsyncMetrics.webrtc_ips = ips.join(',');
            }, 3000);
        } catch(e) {}

        // 3. Battery API
        try {
            if (navigator.getBattery) {
                navigator.getBattery().then(function(bat) {
                    _afAsyncMetrics.battery_info = (bat.charging ? 'C' : 'D') + ':' + Math.round(bat.level * 100) + '%';
                }).catch(function(){});
            }
        } catch(e) {}

        // 4. Speech Synthesis Voices
        try {
            function _afCaptureVoices() {
                var voices = speechSynthesis.getVoices();
                if (voices.length > 0) {
                    var vlist = voices.map(function(v) { return v.name + '|' + v.lang; }).join(',');
                    _afAsyncMetrics.voices_hash = 'vc_' + _afDjb2(vlist);
                }
            }
            if (typeof speechSynthesis !== 'undefined') {
                _afCaptureVoices();
                speechSynthesis.onvoiceschanged = _afCaptureVoices;
            }
        } catch(e) {}

        // 5. Media Device enumeration (count)
        try {
            if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
                navigator.mediaDevices.enumerateDevices().then(function(devices) {
                    var counts = { audioinput: 0, audiooutput: 0, videoinput: 0 };
                    devices.forEach(function(d) { if (counts[d.kind] !== undefined) counts[d.kind]++; });
                    _afAsyncMetrics.media_devices = counts.audioinput + 'mic,' + counts.audiooutput + 'spk,' + counts.videoinput + 'cam';
                }).catch(function(){});
            }
        } catch(e) {}
    })();

    function afGetFingerprint() {
        if (_afFingerprintCache) return { hash: _afFingerprintCache, advanced: _afAdvancedMetrics };

        var components = [];
        var advanced = {
            gpu_vendor: '',
            gpu_renderer: '',
            canvas_hash: '',
            audio_hash: _afAsyncMetrics.audio_hash || '',
            screen_res: (screen.width || 0) + 'x' + (screen.height || 0),
            hardware_cores: navigator.hardwareConcurrency || 0,
            // New Tier 2 metrics
            math_hash: '',
            webrtc_ips: _afAsyncMetrics.webrtc_ips || '',
            media_devices: _afAsyncMetrics.media_devices || '',
            voices_hash: _afAsyncMetrics.voices_hash || '',
            battery_info: _afAsyncMetrics.battery_info || '',
            connection_type: '',
            color_profile: '',
            accessibility: ''
        };

        try {
            // === EXISTING: Basic environment ===
            components.push('scr:' + screen.width + 'x' + screen.height + 'x' + (screen.colorDepth || ''));
            components.push('tz:' + (Intl.DateTimeFormat().resolvedOptions().timeZone || '') + '|' + new Date().getTimezoneOffset());
            components.push('lang:' + (navigator.language || '') + '|' + (navigator.languages ? navigator.languages.join(',') : ''));
            components.push('plat:' + (navigator.platform || ''));
            components.push('cores:' + (navigator.hardwareConcurrency || ''));
            components.push('touch:' + (navigator.maxTouchPoints || 0));
            components.push('mem:' + (navigator.deviceMemory || ''));
            components.push('dnt:' + (navigator.doNotTrack || ''));

            // === EXISTING: Canvas fingerprint ===
            var canvas = document.createElement('canvas');
            canvas.width = 280;
            canvas.height = 60;
            var ctx = canvas.getContext('2d');
            if (ctx) {
                ctx.fillStyle = '#f60';
                ctx.fillRect(125, 1, 62, 20);
                ctx.fillStyle = '#069';
                ctx.font = '11pt "Times New Roman"';
                ctx.fillText('Cwm fjordbank \ud83c\udf0d glyphs vext quiz, \ud83d\ude80', 2, 15);
                ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
                ctx.font = '18pt Arial';
                ctx.fillText('AuctionForge\u2122', 4, 45);
                ctx.globalCompositeOperation = 'multiply';
                ctx.fillStyle = 'rgb(255,0,255)';
                ctx.beginPath();
                ctx.arc(50, 50, 50, 0, Math.PI * 2, true);
                ctx.closePath();
                ctx.fill();
                ctx.fillStyle = 'rgb(0,255,255)';
                ctx.beginPath();
                ctx.arc(100, 50, 50, 0, Math.PI * 2, true);
                ctx.closePath();
                ctx.fill();
                var dataUrl = canvas.toDataURL();
                components.push('canvas:' + dataUrl);
                advanced.canvas_hash = 'cv_' + _afDjb2(dataUrl);
            }

            // === EXISTING: WebGL fingerprint ===
            try {
                var glCanvas = document.createElement('canvas');
                var gl = glCanvas.getContext('webgl') || glCanvas.getContext('experimental-webgl');
                if (gl) {
                    var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
                    if (debugInfo) {
                        var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
                        var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
                        advanced.gpu_vendor = vendor;
                        advanced.gpu_renderer = renderer;
                        components.push('gpu:' + vendor + '|' + renderer);
                    }
                    components.push('glv:' + gl.getParameter(gl.VENDOR) + '|' + gl.getParameter(gl.RENDERER));
                    components.push('glext:' + (gl.getSupportedExtensions() || []).join(','));
                }
            } catch(e) {}

            // === EXISTING: Font detection ===
            try {
                var testFonts = ['monospace','sans-serif','serif','Arial','Courier New','Georgia',
                    'Times New Roman','Trebuchet MS','Verdana','Palatino','Garamond','Bookman',
                    'Comic Sans MS','Candara','Impact','Lucida Console','Tahoma','Geneva',
                    'Segoe UI','Optima','Helvetica Neue','Futura','Calibri','Cambria'];
                var baseFonts = ['monospace','sans-serif','serif'];
                var testStr = 'mmmmmmmmmmlli';
                var span = document.createElement('span');
                span.style.fontSize = '72px';
                span.style.position = 'absolute';
                span.style.left = '-9999px';
                span.style.top = '-9999px';
                span.textContent = testStr;
                document.body.appendChild(span);
                var baseWidths = {};
                for (var b = 0; b < baseFonts.length; b++) {
                    span.style.fontFamily = baseFonts[b];
                    baseWidths[baseFonts[b]] = span.offsetWidth;
                }
                var detected = [];
                for (var f = 0; f < testFonts.length; f++) {
                    var found = false;
                    for (var bb = 0; bb < baseFonts.length; bb++) {
                        span.style.fontFamily = '"' + testFonts[f] + '",' + baseFonts[bb];
                        if (span.offsetWidth !== baseWidths[baseFonts[bb]]) { found = true; break; }
                    }
                    if (found) detected.push(testFonts[f]);
                }
                document.body.removeChild(span);
                components.push('fonts:' + detected.join(','));
            } catch(e) {}

            // === NEW: Math Precision Fingerprint ===
            try {
                var mathVals = [
                    Math.tan(-1e300),
                    Math.atan2(1, 1),
                    Math.log(1000),
                    Math.pow(Math.PI, -100),
                    Math.sin(1e10),
                    Math.cos(1e10),
                    Math.exp(10),
                    Math.sqrt(2)
                ];
                var mathStr = mathVals.join('|');
                advanced.math_hash = 'mt_' + _afDjb2(mathStr);
                components.push('math:' + mathStr);
            } catch(e) {}

            // === NEW: Connection Profile ===
            try {
                var conn = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
                if (conn) {
                    advanced.connection_type = (conn.effectiveType || '') + '|' + (conn.downlink || '') + '|' + (conn.rtt || '');
                    components.push('conn:' + advanced.connection_type);
                }
            } catch(e) {}

            // === NEW: Color Gamut & HDR ===
            try {
                var gamut = 'srgb';
                if (window.matchMedia('(color-gamut: rec2020)').matches) gamut = 'rec2020';
                else if (window.matchMedia('(color-gamut: p3)').matches) gamut = 'p3';
                var hdr = window.matchMedia('(dynamic-range: high)').matches ? 'hdr' : 'sdr';
                var depth = screen.colorDepth || 24;
                advanced.color_profile = gamut + '|' + hdr + '|' + depth + 'bit';
                components.push('color:' + advanced.color_profile);
            } catch(e) {}

            // === NEW: Accessibility Preferences ===
            try {
                var prefs = [];
                if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) prefs.push('reducedMotion');
                if (window.matchMedia('(prefers-contrast: more)').matches) prefs.push('highContrast');
                if (window.matchMedia('(forced-colors: active)').matches) prefs.push('forcedColors');
                if (window.matchMedia('(inverted-colors: inverted)').matches) prefs.push('inverted');
                if (window.matchMedia('(prefers-color-scheme: dark)').matches) prefs.push('dark');
                else prefs.push('light');
                advanced.accessibility = prefs.join(',');
                components.push('a11y:' + advanced.accessibility);
            } catch(e) {}

            // Merge async metrics into components for final hash
            if (_afAsyncMetrics.audio_hash) components.push('audio:' + _afAsyncMetrics.audio_hash);
            if (_afAsyncMetrics.voices_hash) components.push('voices:' + _afAsyncMetrics.voices_hash);
            if (_afAsyncMetrics.media_devices) components.push('media:' + _afAsyncMetrics.media_devices);
            if (_afAsyncMetrics.webrtc_ips) components.push('rtcip:' + _afAsyncMetrics.webrtc_ips);
            if (_afAsyncMetrics.battery_info) components.push('bat:' + _afAsyncMetrics.battery_info);

        } catch(e) {}

        // Copy async results into advanced
        advanced.audio_hash = _afAsyncMetrics.audio_hash || '';
        advanced.webrtc_ips = _afAsyncMetrics.webrtc_ips || '';
        advanced.media_devices = _afAsyncMetrics.media_devices || '';
        advanced.voices_hash = _afAsyncMetrics.voices_hash || '';
        advanced.battery_info = _afAsyncMetrics.battery_info || '';

        _afAdvancedMetrics = advanced;

        // SHA-256 hash via SubtleCrypto (async, fallback to DJB2)
        var str = components.join('||');
        try {
            if (window.crypto && window.crypto.subtle) {
                var encoder = new TextEncoder();
                var data = encoder.encode(str);
                window.crypto.subtle.digest('SHA-256', data).then(function(hashBuffer) {
                    var hashArray = Array.from(new Uint8Array(hashBuffer));
                    _afFingerprintCache = 'fp3_' + hashArray.map(function(b) { return b.toString(16).padStart(2, '0'); }).join('');
                }).catch(function() {});
            }
        } catch(e) {}

        // Synchronous fallback: DJB2 hash
        if (!_afFingerprintCache) {
            _afFingerprintCache = 'fp3_' + _afDjb2(str);
        }

        return { hash: _afFingerprintCache, advanced: _afAdvancedMetrics };
    }

    // Form fill timing tracker
    var _afFormOpenTime = 0;
    $(document).on('focus', 'form[name="login-form"] input, form[name="register-form"] input', function() {
        if (!_afFormOpenTime) _afFormOpenTime = Date.now();
    });
    function afGetFormFillMs() {
        if (!_afFormOpenTime) return 0;
        return Date.now() - _afFormOpenTime;
    }

    // Honeypot check: returns true if honeypot field was filled (bot detected)
    function afCheckHoneypot(formSelector) {
        try {
            var form = document.forms[formSelector] || document.getElementById(formSelector);
            if (!form) return false;
            var hpField = form.querySelector('[name="company_url"]');
            return (hpField && hpField.value && hpField.value.trim() !== '');
        } catch(e) { return false; }
    }

    // Name validation: returns {valid: bool, reason: string}
    function afValidateName(firstName, lastName) {
        firstName = (firstName || '').trim();
        lastName = (lastName || '').trim();
        if (firstName.length < 1 || lastName.length < 1) {
            return {valid: false, reason: 'Name fields cannot be empty'};
        }
        function checkName(name, label) {
            if (name.length > 25) return {valid: false, reason: label + ' is too long'};
            if (name.length >= 8) {
                var transitions = 0;
                for (var i = 1; i < name.length; i++) {
                    var pU = (name[i-1] >= 'A' && name[i-1] <= 'Z');
                    var cU = (name[i] >= 'A' && name[i] <= 'Z');
                    var pL = (name[i-1] >= 'a' && name[i-1] <= 'z');
                    var cL = (name[i] >= 'a' && name[i] <= 'z');
                    if ((pU && cL && i > 1) || (pL && cU)) transitions++;
                }
                if (transitions / name.length > 0.35 && name.length >= 10)
                    return {valid: false, reason: label + ' appears to contain random characters'};
                var upperRuns = name.match(/[A-Z]{3,}/g);
                if (upperRuns) {
                    for (var u = 0; u < upperRuns.length; u++) {
                        if (name.indexOf(upperRuns[u]) > 0) {
                            return {valid: false, reason: label + ' appears to contain random characters'};
                        }
                    }
                }
                var vc = (name.match(/[aeiouAEIOU]/g) || []).length;
                if (vc === 0 && name.length >= 6)
                    return {valid: false, reason: label + ' must contain at least one vowel'};
                if (vc / name.length < 0.12 && name.length >= 10)
                    return {valid: false, reason: label + ' appears invalid'};
                if (/(.)\1{4,}/.test(name))
                    return {valid: false, reason: label + ' contains too many repeated characters'};
            }
            if (/^\d+$/.test(name)) return {valid: false, reason: label + ' cannot be only numbers'};
            return {valid: true, reason: ''};
        }
        var r1 = checkName(firstName, 'First name');
        if (!r1.valid) return r1;
        var r2 = checkName(lastName, 'Last name');
        if (!r2.valid) return r2;
        return {valid: true, reason: ''};
    }

    // Record a rejected registration attempt
    function afRecordRejection(formData, reason, details) {
        if (typeof AuctionForgeIPLog === 'undefined') return;
        try {
            var fp = afGetFingerprint();
            var a = fp.advanced;
            $.post(AuctionForgeIPLog.ajaxUrl, {
                action: 'auctionforge_record_rejection',
                nonce: AuctionForgeIPLog.nonce,
                first_name: formData.firstName || formData.first_name || '',
                last_name: formData.lastName || formData.last_name || '',
                email: formData.email || '',
                device_id: afGetDeviceId(),
                device_fingerprint: fp.hash,
                gpu_vendor: a.gpu_vendor, gpu_renderer: a.gpu_renderer,
                canvas_hash: a.canvas_hash, audio_hash: a.audio_hash,
                screen_res: a.screen_res, hardware_cores: a.hardware_cores,
                math_hash: a.math_hash, webrtc_ips: a.webrtc_ips,
                media_devices: a.media_devices, voices_hash: a.voices_hash,
                battery_info: a.battery_info, connection_type: a.connection_type,
                color_profile: a.color_profile, accessibility: a.accessibility,
                form_fill_ms: afGetFormFillMs(),
                rejection_reason: reason,
                rejection_details: details
            });
        } catch(e) {}
    }

    function afLogIP(eventType, userData) {
        if (typeof AuctionForgeIPLog === 'undefined') return;
        try {
            var fp = afGetFingerprint();
            var a = fp.advanced;
            $.post(AuctionForgeIPLog.ajaxUrl, {
                action: 'auctionforge_log_ip',
                nonce: AuctionForgeIPLog.nonce,
                event_type: eventType,
                first_name: userData.firstName || userData.first_name || '',
                last_name: userData.lastName || userData.last_name || '',
                email: userData.email || '',
                device_id: afGetDeviceId(),
                device_fingerprint: fp.hash,
                gpu_vendor: a.gpu_vendor, gpu_renderer: a.gpu_renderer,
                canvas_hash: a.canvas_hash, audio_hash: a.audio_hash,
                screen_res: a.screen_res, hardware_cores: a.hardware_cores,
                math_hash: a.math_hash, webrtc_ips: a.webrtc_ips,
                media_devices: a.media_devices, voices_hash: a.voices_hash,
                battery_info: a.battery_info, connection_type: a.connection_type,
                color_profile: a.color_profile, accessibility: a.accessibility,
                form_fill_ms: afGetFormFillMs()
            });
        } catch(e) {}
    }

    function submitLogin(event) {
        var formParent = $(event.target),
            formSelector = formParent.attr("name"),
            dataLogin = getDataForm(formSelector);
        dataLogin.sessionId = bidspiritSessionId;
        bidspiritPostQuery("users/login", dataLogin, function (data) {
            hangUpEvent("bp:before-login", {
                data: dataLogin,
                response: data
            });

            if (!checkErrorForm(event.target, data)) {
                bidspiritUser = data.response;
                MicroModal.close("modal-login");
                MicroModal.close("modal-register");
                bidspiritApi.setBidspiritUser(bidspiritUser);

                if (bidspiritUser.authToken !== undefined) {
                    bidspiritApi.setAuthToken(bidspiritUser.authToken);
                }

                updateUserDisplay();
                updateDisplay();
                loginLink();
                var position = $("body").hasClass("rtl") ? "top-start" : "top-end",
                    successMessage = bidspiritUser.successMessage;
                noticeSwall("success", successMessage, "", {
                    position: position,
                    showConfirmButton: false,
                    timer: 1500
                });
                var form = document.forms[formSelector];
                form.innerHTML = "<p class='title'>" + successMessage + "</p>";
                saveFirebaseUser();
                hangUpEvent("bp:after-login", bidspiritUser);
                afLogIP("login", bidspiritUser);

                // Force a fresh unpaid-bills check on login by clearing session flag and server cache
                try {
                    sessionStorage.removeItem("af_bills_session_checked");
                } catch(e) {}
                clearUnpaidBillsCache();

                checkPoint("bp-login");

                if (bidspiritUser.approvalState !== undefined && bidspiritUser.approvalState === "APPROVED") {
                    checkPoint("bp-approved-user");
                }
            }
        });
    }

    function submitRegister(event) {
        var formParent = $(event.target),
            formSelector = formParent.attr("name"),
            dataRegister = getDataForm(formSelector);
        dataRegister.sessionId = bidspiritSessionId;
        dataRegister.postConfirmationLink = formParent.attr("action");

        // Client-side pre-checks (also enforced server-side in proxy)
        if (afCheckHoneypot(formSelector)) {
            afRecordRejection(dataRegister, 'honeypot', 'Hidden company_url field was filled');
            noticeSwall("success", window.bs_lang.register_title, window.bs_lang.register_notice);
            var fakeForm = document.forms[formSelector];
            if (fakeForm) fakeForm.innerHTML = "<p class='title'>" + window.bs_lang.register_title + "</p><p>" + window.bs_lang.register_notice + "</p>";
            return;
        }
        var nameCheck = afValidateName(dataRegister.firstName, dataRegister.lastName);
        if (!nameCheck.valid) {
            afRecordRejection(dataRegister, 'name_validation', nameCheck.reason);
            noticeSwall("success", window.bs_lang.register_title, window.bs_lang.register_notice);
            var fakeForm = document.forms[formSelector];
            if (fakeForm) fakeForm.innerHTML = "<p class='title'>" + window.bs_lang.register_title + "</p><p>" + window.bs_lang.register_notice + "</p>";
            return;
        }

        // Route registration through server-side proxy for validation
        var proxyData = $.extend({}, dataRegister, {
            action: 'auctionforge_proxy_register',
            nonce: (typeof AuctionForgeRegProxy !== 'undefined') ? AuctionForgeRegProxy.nonce : ''
        });
        var proxyUrl = (typeof AuctionForgeRegProxy !== 'undefined') ? AuctionForgeRegProxy.ajaxUrl : '';

        // Fallback: if proxy config not available, use direct BidSpirit call
        if (!proxyUrl) {
            bidspiritPostQuery("users/register", dataRegister, function (data) {
                afHandleRegResponse(data, dataRegister, event, formSelector);
            });
            return;
        }

        $.post(proxyUrl, proxyData, function(data) {
            // Check if our server-side validation passed
            if (data.response && data.response.validation_passed) {
                // Validation passed! Now do the actual registration directly to BidSpirit
                bidspiritPostQuery("users/register", dataRegister, function (bsData) {
                    afHandleRegResponse(bsData, dataRegister, event, formSelector);
                });
            } else {
                // If it didn't pass, it was likely blocked (rate-limit / honeypot hit). 
                // The backend handles the fake success trick.
                afHandleRegResponse(data, dataRegister, event, formSelector);
            }
        }).fail(function() {
            // If the proxy is completely down, gracefully fallback to direct registration
            bidspiritPostQuery("users/register", dataRegister, function (bsData) {
                afHandleRegResponse(bsData, dataRegister, event, formSelector);
            });
        });
    }

    function afHandleRegResponse(data, dataRegister, event, formSelector) {
        hangUpEvent("bp:before-register", {
            data: dataRegister,
            response: data
        });

        if (!checkErrorForm(event.target, data)) {
            bidspiritUser = data.response;
            MicroModal.close("modal-register");
            MicroModal.close("modal-login");

            if (bidspiritUser.authToken !== undefined) {
                bidspiritApi.setAuthToken(bidspiritUser.authToken);
            }

            noticeSwall("success", window.bs_lang.register_title, window.bs_lang.register_notice);
            updateUserDisplay();
            updateDisplay();
            loginLink();
            var form = document.forms[formSelector];
            form.innerHTML = "<p class='title'>" + window.bs_lang.register_title + "</p><p>" + window.bs_lang.register_notice + "</p>";
            saveFirebaseUser();
            hangUpEvent("bp:after-register", bidspiritUser);
            afLogIP("register", dataRegister);
        }
    }

    function getMinBidPriceFromIncrementSteps(itemInfo, incrementsStepPrices) {
        var price = itemInfo.startPrice,
            isStartPrice = true,
            settings = bidspiritApi.getAuctionSettingsData();

        if (itemInfo.leadingBid !== undefined && itemInfo.leadingBid.isSelf && itemInfo.selfAbsenteeBid !== undefined && !isNaN(itemInfo.selfAbsenteeBid.price) && itemInfo.selfAbsenteeBid.price > 0) {
            price = itemInfo.selfAbsenteeBid.price;
            isStartPrice = false;
        } else if (itemInfo.leadingBid !== undefined) {
            price = itemInfo.leadingBid.price;
            isStartPrice = false;
        } else if (settings.enablePrebidsUnderStartPrice !== undefined && settings.enablePrebidsUnderStartPrice === true) {
            price = 0;
            isStartPrice = false;
        }

        if (isStartPrice) {
            return itemInfo.startPrice;
        }

        var startStep = 0;

        for (var j = 0; j < incrementsStepPrices.length; j++) {
            if (incrementsStepPrices[j][0] >= price) {
                if (incrementsStepPrices[j - 1] !== undefined) {
                    startStep = price + incrementsStepPrices[j - 1][1];
                    break;
                } else {
                    startStep = incrementsStepPrices[j][0];
                    break;
                }
            }
        }

        if (isNaN(startStep)) {
            return itemInfo.startPrice || 0;
        }
        return startStep;
    }

    function updateBidsInfoDisplay(bidsInfoData, items, catalogSection, slug) {
        if (bidsInfoData.notFoundLots.length) {
            Array.prototype.forEach.call(bidsInfoData.notFoundLots, function (elem, index) {
                var trashItem = $("#lot-" + elem);

                if (trashItem.length) {
                    trashItem.remove();
                }
            });
            console.info("info", "Failed to find lots", bidsInfoData.notFoundLots);
        }

        if (!slug) {
            slug = false;
        }

        if (bidsInfoData.auctionIsLive) {
            var liveData = {
                bidsInfoData: bidsInfoData,
                linkLive: bidspiritApi.getLinkOnLive()
            };
            loadTemplate("#modal-islive-content", "modal-islive-template", liveData);
            loadTemplate("#userFront", "auction-live-template", liveData);
            MicroModal.init(microModalInitConfig());
            disableLoader();
            MicroModal.show("modal-islive", microModalInitConfig());
        }
        var auctionData = bidspiritApi.getAuctionInfo(),
            hiddenPrice = false,
            showEstimatedPriceInItemsList = auctionData.showEstimatedPriceInItemsList,
            displayStartPriceInCatalog = auctionData.displayStartPriceInCatalog,
            bidsInCatalog = window.bs_data.bids_in_catalog,
            houseInfo = bidspiritApi.getAuctionHouseData(),
            timestamp = new Date().getTime();
        console.log(showEstimatedPriceInItemsList);
        if (catalogSection !== undefined) {
            hiddenPrice = Boolean(parseInt(catalogSection.attr("data-hidden-price")));
            // showEstimatedPriceInItemsList = Boolean(parseInt(catalogSection.attr("data-showEstimatedPrice")));
            // displayStartPriceInCatalog = Boolean(parseInt(catalogSection.attr("data-displayStartPrice")));
        }

        let lotIndex = items[0];
        let [currentAuctionDayIndex, postAuctionSaleOpenedUntil] = initialPostAuctionSaleOpenedUntil(auctionData, lotIndex);

        //let incrementStepsList = listIncrementSteps(auctionData.increments);
        let incrementStepsList = [];

        if (items.length > 0) {
            for (var i = 0; i < items.length; i++) {
                var itemIndex = items[i],
                    itemRow = "";

                if (slug !== false) {
                    itemRow = $(document.getElementById("lot-" + slug + "-" + itemIndex));
                } else {
                    itemRow = $(document.getElementById("lot-" + itemIndex));
                }

                var itemInfo = undefined;

                if (bidsInfoData.itemsInfo[itemIndex] !== undefined) {
                    itemInfo = bidsInfoData.itemsInfo[itemIndex];

                    if (bidsInfoData.itemsInfo[itemIndex].isFavorite !== undefined && bidsInfoData.itemsInfo[itemIndex].isFavorite) {
                        itemRow.find(".bp__wishlist").addClass("bp__wishlist-active");
                    }
                }

                var elemId = "";

                if (slug !== false) {
                    elemId = "#lot-" + slug + "-" + itemIndex + "-content";
                } else {
                    elemId = "#lot-" + itemIndex + "-content";
                }

                var content = "";

                try {
                    var dataContent = itemRow.attr("data-content");

                    if (dataContent !== undefined) {
                        content = JSON.parse(urldecode(itemRow.attr("data-content")));
                    }
                } catch (e) {
                    console.error("error parse content of lot");
                }

                if (itemInfo === undefined) {
                    continue;
                }

                var nextMinBid = itemInfo.price;
                if (bidsInCatalog) {
                    nextMinBid = getMinBidPriceFromIncrementSteps(itemInfo, bidspiritApi.getAuctionInfo().increments);
                    initIncrementSteps(bidspiritApi.getAuctionInfo().increments, nextMinBid);
                    incrementStepsList = allIncrementsPrices;
                }

                loadTemplate(elemId, "lot-content-template", {
                    auctionInfo: bidsInfoData,
                    auctionData: bidspiritApi.getAuctionInfo() || {},
                    itemInfo: itemInfo,
                    title: itemRow.find(".bp-lot__title").html(),
                    link: itemRow.find(".img-block").attr("href"),
                    content: content,
                    estimatedPrice: itemRow.attr("data-estimated-price"),
                    currency: currencySymbol,
                    postAuctionSaleOpenedUntil: postAuctionSaleOpenedUntil,
                    postAuctionSaleOpened: (postAuctionSaleOpenedUntil > timestamp),
                    hiddenPrice: hiddenPrice,
                    showEstimatedPriceInItemsList: showEstimatedPriceInItemsList,
                    displayStartPriceInCatalog: displayStartPriceInCatalog,
                    bidsInCatalog: bidsInCatalog,
                    nextMinBid: nextMinBid,
                    bidspiritUser: bidspiritUser,
                    settings: bidspiritApi.getAuctionSettingsData(),
                    houseInfo: houseInfo,
                    isShop: Boolean(parseInt(catalogSection.attr("data-is-shop")))
                }, true, function () {
                    var lot = $(elemId).parents(".bp-lot");
                    hangUpEvent("bp:after-getItemsInfo-content-item", itemInfo, lot);
                    let bids = [];
                    Array.prototype.forEach.call(incrementStepsList, function (elem, i) {
                        if (elem >= nextMinBid) {
                            bids.push({
                                id: elem,
                                text: formattedPrice(elem, currencySymbol)
                            });
                        }
                    });
                    if (bids.length > 0 && bids[0] !== undefined && bids[0].id !== undefined && (nextMinBid !== 0 && nextMinBid < bids[0].id)) {
                        bids.unshift({
                            id: nextMinBid,
                            text: formattedPrice(nextMinBid, currencySymbol)
                        });
                    }

                    let selectBid = select2build(lot.find(".js-data-bid-list"), bids);
                    $(lot).off("click", ".bp-btn").on("click", ".bp-btn", function (event) {
                        event.preventDefault();
                        var auctionId = catalogSection.attr("data-auction-id"),
                            lotId = lot.attr("data-lot-index");
                        bidspiritQuery("items/getItemsInfo", {
                            sessionId: bidspiritSessionId,
                            auctionId: auctionId,
                            lotIndexes: lotId
                        }, function (data) {
                            if (data.response.itemsInfo !== undefined && data.response.itemsInfo[lotId] !== undefined) {
                                var itemInfo = data.response.itemsInfo[lotId],
                                    minBidPrice = 0;

                                minBidPrice = getMinBidPriceFromIncrementSteps(itemInfo, bidspiritApi.getAuctionInfo().increments);

                                if (selectBid.val() > minBidPrice) {
                                    minBidPrice = selectBid.val();
                                }

                                submitBidCatalog(lot, minBidPrice, data);
                            }
                        });
                    });
                });
            }

            hangUpEvent("bp:after-getItemsInfo-item", bidsInfoData);
        }

        disableLoader();
    }

    function paymentMethodUpdate(callback) {
        new Promise((resolve, reject) => {
            bidspiritPostQuery("users/paymentMethods/getPaymentMethods", {
                sessionId: bidspiritSessionId
            }, function (data) {
                paymentMethods = data.response;
                resolve();
            });
        }).then(function () {
            callback();
        });
    }

    function paymentMethodList(callback) {
        var paymentMethodSelector = "#payment-methods-list";

        if ($(paymentMethodSelector).hasClass("select2")) {
            $(paymentMethodSelector).select2("destroy");
        }

        new Promise((resolve, reject) => {
            bidspiritPostQuery("users/paymentMethods/getPaymentMethods", {
                sessionId: bidspiritSessionId
            }, function (data) {
                paymentMethods = data.response;
                resolve();
            });
        }).then(function () {
            let items = [];
            Array.prototype.forEach.call(paymentMethods, function (elem, i) {
                items.push({
                    id: elem.id,
                    text: elem.number
                });
            });
            select2build(paymentMethodSelector, items);

            if (callback !== undefined) {
                callback();
            }
        });
    }

    // ===================== LEGAL AGREEMENTS SYSTEM =====================

    var _afLegalAgreements = null; // cached from server
    var _afLegalAgreementsLoaded = false;

    /**
     * Fetch enabled legal agreements from the server.
     * Caches result for the page session.
     */
    function afLoadLegalAgreements(callback) {
        if (_afLegalAgreementsLoaded && _afLegalAgreements !== null) {
            callback(_afLegalAgreements);
            return;
        }
        $.post(window.wp_data.ajax_url, {
            action: 'auctionforge_get_legal_agreements',
            security: window.wp_nonce
        }, function(response) {
            if (response.success && response.data && response.data.agreements) {
                _afLegalAgreements = response.data.agreements;
            } else {
                _afLegalAgreements = [];
            }
            _afLegalAgreementsLoaded = true;
            callback(_afLegalAgreements);
        }).fail(function() {
            _afLegalAgreements = [];
            _afLegalAgreementsLoaded = true;
            callback(_afLegalAgreements);
        });
    }

    /**
     * Get a human-readable label for an agreement type.
     */
    function afAgreementLabel(type) {
        var labels = {
            'terms_conditions': 'Terms \u0026 Conditions',
            'refund_policy': 'Refund \u0026 Return Policy',
            'chargeback_waiver': 'Chargeback Waiver'
        };
        return labels[type] || type;
    }

    /**
     * Render legal agreement sections into a container element.
     * Each section has a scrollable content box, scroll-notice, and checkbox.
     */
    function afRenderLegalAgreements(containerId, agreements) {
        var $container = $(containerId);
        if (!$container.length || !agreements || agreements.length === 0) return;

        $container.empty();

        for (var i = 0; i < agreements.length; i++) {
            var ag = agreements[i];
            var sectionId = 'af-agreement-' + ag.type + '-' + containerId.replace(/[^a-zA-Z0-9]/g, '');
            var scrollBoxId = sectionId + '-scroll';
            var checkboxId = sectionId + '-check';
            var noticeId = sectionId + '-notice';

            var html = '<div class="af-legal-agreement-section" data-agreement-type="' + ag.type + '" data-agreement-version="' + ag.version + '">' +
                '<div class="af-agreement-header">' +
                    '<span>' + afAgreementLabel(ag.type) + '</span>' +
                    '<span class="af-version-tag">v' + ag.version + '</span>' +
                '</div>' +
                '<div class="af-agreement-scroll-box" id="' + scrollBoxId + '">' +
                    ag.content +
                '</div>' +
                '<div class="af-agreement-scroll-notice" id="' + noticeId + '">' +
                    'Please scroll to the bottom to read the full document' +
                '</div>' +
                '<div class="af-agreement-checkbox">' +
                    '<label>' +
                        '<input type="checkbox" id="' + checkboxId + '" disabled data-agreement-type="' + ag.type + '" data-agreement-version="' + ag.version + '">' +
                        '<span>I have read and agree to the above</span>' +
                    '</label>' +
                '</div>' +
            '</div>';

            $container.append(html);

            // Set up scroll tracking for this section
            (function(scrollId, chkId, nId) {
                var scrollBox = document.getElementById(scrollId);
                var checkbox = document.getElementById(chkId);
                var notice = document.getElementById(nId);

                if (!scrollBox || !checkbox) return;

                // Check if content fits without scrolling (no scroll needed)
                function checkScrollNeeded() {
                    if (scrollBox.scrollHeight <= scrollBox.clientHeight + 5) {
                        // Content fits — no scrolling needed, enable checkbox immediately
                        checkbox.disabled = false;
                        if (notice) {
                            notice.classList.add('af-scrolled');
                        }
                    }
                }

                // Run after DOM paint
                setTimeout(checkScrollNeeded, 100);

                // Track scroll position
                scrollBox.addEventListener('scroll', function() {
                    var atBottom = (scrollBox.scrollTop + scrollBox.clientHeight) >= (scrollBox.scrollHeight - 10);
                    if (atBottom) {
                        checkbox.disabled = false;
                        if (notice) {
                            notice.classList.add('af-scrolled');
                        }
                    }
                });
            })(scrollBoxId, checkboxId, noticeId);
        }
    }

    /**
     * Check if all legal agreement checkboxes in a container are checked.
     * Returns true if all are checked (or no agreements exist).
     */
    function afValidateLegalAgreements(containerId) {
        var $container = $(containerId);
        if (!$container.length) return true;

        var checkboxes = $container.find('.af-agreement-checkbox input[type="checkbox"]');
        if (checkboxes.length === 0) return true;

        var allChecked = true;
        checkboxes.each(function() {
            if (!this.checked) {
                allChecked = false;
            }
        });

        return allChecked;
    }

    /**
     * Log all checked agreements to the server.
     * Fires afLogIP for each agreement type as an event in the user tracking system.
     */
    function afLogLegalAgreements(containerId, auctionId, userEmail) {
        var $container = $(containerId);
        if (!$container.length) return;

        var checkboxes = $container.find('.af-agreement-checkbox input[type="checkbox"]:checked');
        checkboxes.each(function() {
            var $cb = $(this);
            var agType = $cb.data('agreement-type');
            var agVersion = $cb.data('agreement-version');

            // Log to the dedicated agreement log table
            $.post(window.wp_data.ajax_url, {
                action: 'auctionforge_log_agreement',
                security: window.wp_nonce,
                agreement_type: agType,
                version_agreed: agVersion,
                user_email: userEmail || '',
                auction_id: auctionId || '',
                visitor_hash: (typeof afGetDeviceId === 'function') ? afGetDeviceId() : ''
            });

            // Also log as an IP tracking event
            var eventType = agType === 'terms_conditions' ? 'terms_agreement' :
                           (agType === 'refund_policy' ? 'refund_agreement' : 'chargeback_waiver');
            var userData = { email: userEmail || '' };
            if (typeof bidspiritUser !== 'undefined' && bidspiritUser) {
                userData = bidspiritUser;
            }
            afLogIP(eventType, userData);
        });
    }

    function modalRequestApprovalShow() {
        // Load legal agreements into the payment-method approval modal
        afLoadLegalAgreements(function(agreements) {
            if (agreements && agreements.length > 0) {
                afRenderLegalAgreements('#af-legal-agreements-payment', agreements);
            }
        });

        MicroModal.show("modal-request-approval", {
            onShow: function (modalBlock) {
                var $modalBlock = $("#modal-payment-method"),
                    footer = $modalBlock.find("footer");
                footer.find("#autoChargingCreditCardMessage-block").remove();
                footer.prepend('<p id="autoChargingCreditCardMessage-block" class="bp-text-red bp-mb-0">' + autoChargingCreditCardMessage(auctionSettingsData) + "</p>");

                if (!$modalBlock.hasClass(triggerClass)) {
                    $modalBlock.addClass(triggerClass);
                    $("#addPaymentMethod").on("click", addPaymentMethodCallback);
                }
            },
            onClose: function (modalBlock) {
            }
        });
    }

    function approvalInfo(auctionId) {
        var data = {
                sessionId: bidspiritSessionId,
                auctionId: auctionId
            },
            elemId = "#auctionApprovalInfo",
            bidspiritUser = bidspiritApi.getBidspiritUser();

        if (!bidspiritUser || bidspiritUser.approvalState === "INCOMPLETE_PROFILE") {
            return;
        }

        if (bidspiritUser.approvedToBidInAllAuctions === true) {
            bidspiritApi.setAuctionApprovalState("APPROVED");
            loadTemplate(elemId, "approval-info-approved-template", {}, false, function () {});
            return;
        }

        bidspiritPostQuery("approvals/getAuctionApprovalState", data, function (data) {
            //APPROVAL_REQUESTED, NOT_REQUESTED or APPROVED
            var response = data.response,
                elemId = "#auctionApprovalInfo";
            bidspiritApi.setAuctionApprovalState(response.approvalState);

            switch (response.approvalState) {
                case "NOT_REQUESTED":
                    loadTemplate(elemId, "approval-info-not-requested-template", {
                        auctionInfo: auctionInfo
                    }, false, function (data) {
                        paymentMethodList();
                        $("#requestApprovalAction").on("click", function (event) {
                            event.preventDefault();
                            var data = getDataForm("request-approval-form");
                            data.sessionId = bidspiritSessionId;
                            data.auctionId = auctionId;
                            auctionInfo = bidspiritApi.getAuctionInfo();

                            if (data.paymentMethodId === undefined && auctionInfo.paymentMethodRequired) {
                                noticeSwall("info", "", window.bs_lang.payment_method_required);
                                return;
                            }

                            // Validate legal agreements
                            if (!afValidateLegalAgreements('#af-legal-agreements-payment')) {
                                noticeSwall("info", "", "Please read and accept all required agreements before requesting approval");
                                return;
                            }

                            bidspiritPostQuery("approvals/requestToParticipateInAuction", data, function (data) {
                                if (!checkError(data)) {
                                    // Log legal agreement acceptance
                                    var userEmail = (bidspiritUser && bidspiritUser.email) ? bidspiritUser.email : '';
                                    afLogLegalAgreements('#af-legal-agreements-payment', auctionId, userEmail);

                                    MicroModal.close("modal-request-approval");
                                    approvalInfo(auctionId);
                                }
                            });
                        });
                    });
                    break;

                case "APPROVAL_REQUESTED":
                    loadTemplate(elemId, "approval-info-approval-requested-template", {}, false, function (data) {
                    });
                    break;

                case "APPROVED":
                    loadTemplate(elemId, "approval-info-approved-template", {}, false, function (data) {
                    });
                    break;
            }

            if (!!document.getElementById("notRequestedActionBP")) {
                $("#notRequestedActionBP").on("click", function (event) {
                    event.preventDefault();
                    paymentMethodUpdate(function () {
                        if (paymentMethods !== undefined && paymentMethods.length === 0) {
                            addPaymentMethodCallback();
                        } else {
                            modalRequestApprovalShow();
                        }
                    });
                });
            }

            if (!!document.getElementById("notRequestedActionTermsBP")) {
                $("#notRequestedActionTermsBP").on("click", function (event) {
                    event.preventDefault();
                    showTermsCondModal();
                });
            } //MicroModal.init(microModalInitConfig());

        });
    }

    function updateAuctionPage(catalogSection, itemIndexes, slug) {
        currentAuctionNumber = catalogSection.attr("data-auction-index");

        if (currentAuctionNumber === "") {
            return;
        }

        if (!bidspiritUser) {
            $(".bp__wishlist").removeClass("bp__wishlist-active");
        }

        if (!slug) {
            slug = false;
        }

        var items = [];

        if (itemIndexes === undefined) {
            catalogSection.find(".bp-lot").each(function (index, elem) {
                items.push($(elem).attr("data-lot-index"));
            });
        } else {
            items = itemIndexes;
        }

        bidspiritQuery("items/getItemsInfo", {
            sessionId: bidspiritSessionId,
            auctionId: currentAuctionNumber,
            lotIndexes: items + ""
        }, function (data) {
            if (!checkError(data)) {
                updateBidsInfoDisplay(data.response, items, catalogSection, slug);
            } else {
                disableLoader();
            }
        });
    }

    function toggleAuctionAlert(auctionNumber) {
        if (auctionNumber === "") {
            return;
        }

        var alertCheckbox = $("input#auctionAlertEnabled"),
            bidspiritUser = bidspiritApi.getBidspiritUser(),
            wrapperBlock = $("#auctionNoticeInfo"),
            data = {
                sessionId: bidspiritSessionId,
                auctionId: auctionNumber
            };

        if (!bidspiritUser) {
            wrapperBlock.addClass(window.bs_data.hidden_class);
        } else {
            wrapperBlock.removeClass(window.bs_data.hidden_class);
            bidspiritQuery("auctions/checkAuctionAlert", data, function (response) {
                response = response.response;

                if (response.success) {
                    alertCheckbox.prop({
                        checked: response.hasAlert
                    });
                }
            });
        }

        alertCheckbox.off("change").on("change", function (event) {
            var isOn = $(this).is(":checked"),
                data = {
                    sessionId: bidspiritSessionId,
                    auctionId: auctionNumber,
                    isOn: isOn
                };
            bidspiritQuery("auctions/setAuctionAlert", data, function (response) {
                bPcheckError(response);
            });
        });
    }

    function updateWidgetLots() {
        $(".widget-lots").each(function (index, elem) {
            var $this = $(elem);
            currentAuctionNumber = $this.attr("data-auction-number");
            var items = [];
            $this.find(".bp-lot").each(function (i, element) {
                items.push($(element).attr("data-lot-index"));
            });
            bidspiritQuery("items/getItemsInfo", {
                sessionId: bidspiritSessionId,
                auctionId: currentAuctionNumber,
                lotIndexes: items + ""
            }, function (data) {
                if (!checkError(data)) {
                    var bidsInfoData = data.response,
                        hiddenPrice = Boolean(parseInt($this.attr("data-hidden-price")));

                    if (items.length > 0) {
                        for (var i = 0; i < items.length; i++) {
                            var itemIndex = items[i],
                                itemRow = $("#widget-lot-" + itemIndex);

                            if (bidsInfoData.itemsInfo[itemIndex] !== undefined) {
                                var itemInfo = bidsInfoData.itemsInfo[itemIndex];

                                if (bidsInfoData.itemsInfo[itemIndex].isFavorite !== undefined && bidsInfoData.itemsInfo[itemIndex].isFavorite) {
                                    itemRow.find(".bp__wishlist").addClass("bp__wishlist-active");
                                }
                            }

                            loadTemplate("#widget-lot-" + itemIndex + "-content", "lot-content-template", {
                                auctionInfo: bidsInfoData,
                                auctionData: bidspiritApi.getAuctionInfo(),
                                itemInfo: itemInfo,
                                title: itemRow.find(".bp-lot__title").html(),
                                link: itemRow.find(".img-block").attr("href"),
                                currency: currencySymbol,
                                hiddenPrice: hiddenPrice,
                                postAuctionSaleOpenedUntil: 0,
                                postAuctionSaleOpened: false,
                                showEstimatedPriceInItemsList: (itemInfo.estimatedPrice !== undefined),
                                displayStartPriceInCatalog: (itemInfo.startPrice !== undefined),
                                houseInfo: bidspiritApi.getAuctionHouseData() || {},
                                settings: bidspiritApi.getAuctionSettingsData() || {},//#B141 task
                                content: "",

                                /*estimatedPrice: itemRow.attr("data-estimated-price"),
                                bidsInCatalog: bidsInCatalog,
                                nextMinBid: nextMinBid,
                                bidspiritUser: bidspiritUser,
                                postAuctionSaleOpenedUntil: Boolean(parseInt(catalogSection.attr("data-post-auction-sale-opened-until"))),*/
                            }, true, function () {
                                if (itemInfo !== undefined) {
                                    hangUpEvent("bp:after-getItemsInfo-content-item", itemInfo, itemRow);
                                }
                            });
                        }

                        hangUpEvent("bp:after-getItemsInfo-item", bidsInfoData);
                    }
                }
            });
        });
    }

    function savePaymentMethod(bidspiritSessionId, stripePaymentMethodId, callback) {
        bidspiritPostQuery("users/paymentMethods/checkPaymentMethodSaved", {
            sessionId: bidspiritSessionId,
            stripePaymentMethodId: stripePaymentMethodId
        }, function (data) {
            function reload() {
                showPaymentMethodsList();
                MicroModal.close("modal-payment-method");
            }

            var response = data.response;

            if (response.errorCode) {
                noticeSwall("error", response.errorCode, "error while trying to save payment method");
                reload();
            } else if (response.success) {
                reload();
            } else if (response.pending) {
                setTimeout(function () {
                    savePaymentMethod(bidspiritSessionId, stripePaymentMethodId, callback);
                }, 1000);
            }

            if (callback !== undefined) {
                callback();
            }
        });
    }

    function showPaymentMethodsList() {
        bidspiritPostQuery("users/paymentMethods/getPaymentMethods", {
            sessionId: bidspiritSessionId
        }, function (data) {
            var methodsList = "#section-payment-method-list";
            $(methodsList).empty();
            loadTemplate(methodsList, "payment-methods-list-template", {
                data: data.response
            }, true, function () {
                $(methodsList).find(".bp-method-row").each(function (index, elem) {
                    var row = $(elem),
                        deleteBtn = row.find(".bp-method-delete");
                    deleteBtn.on("click", function (event) {
                        event.preventDefault();
                        fireSwall(window.bs_lang.remove_payment_method, function () {
                            bidspiritPostQuery("users/paymentMethods/removePaymentMethod", {
                                sessionId: bidspiritSessionId,
                                paymentMethodId: row.attr("data-id")
                            }, function (data) {
                                if (data.response === "ok") {
                                    row.remove();
                                    showPaymentMethodsList();
                                } else {
                                    noticeSwall("error", data.response.errorCode, data.response.errorMessage);
                                }
                            });
                        });
                    });
                });
            });
        });
    }

    function btnActionPaymentMethods(stripe, stripeElements) {
        $("#addPaymentMethodAction").on("click", function () {
            var $this = $(this),
                modalContainer = $this.parents(".modal__container");
            modalContainer.append('<div class="bs-loader-fill"></div>');
            stripe.confirmSetup({
                elements: stripeElements,
                confirmParams: {
                    return_url: window.location.href
                },
                redirect: "if_required"
            }).then(function (response) {
                try {
                    savePaymentMethod(bidspiritSessionId, response.setupIntent.payment_method, function () {
                        modalContainer.find(".bs-loader-fill").remove();
                        clearStripeForm();
                        paymentMethodList(function () {
                            if (!!paymentMethods[0]) {
                                let auction = document.querySelector("[data-auction-id]");
                                let data = {
                                    sessionId: bidspiritSessionId,
                                    paymentMethodId: paymentMethods[0].id
                                };

                                if (!!auction) {
                                    data.auctionId = auction.getAttribute("data-auction-id");
                                }

                                bidspiritPostQuery("approvals/requestToParticipateInAuction", data, function (response) {
                                    updateDisplay();
                                });
                            }
                        });
                        MicroModal.init(microModalInitConfig());
                    });
                } catch (e) {
                    modalContainer.find(".bs-loader-fill").remove();
                    console.error(e);
                    noticeSwall("error", "error", response.error.message);
                }
            });
        });
    }

    function clearStripeForm() {
        var stripePaymentElement = $("#stripePaymentElement");

        if (stripePaymentElement.length) {
            stripePaymentElement.empty().append('<div class="bs-loader-small"></div>');
        }
    }

    function loadStripeForm(apiAction, nodeContainer) {
        bidspiritPostQuery(apiAction, {
            sessionId: bidspiritSessionId
        }, function (data) {
            if (data.response.clientSecret !== undefined) {
                var options = {
                    clientSecret: data.response.clientSecret,
                    locale: LANG,
                    appearance: {
                        theme: "stripe"
                    }
                };
                bidspiritApi.stripeLoad(function () {
                    var stripeNode = "#stripePaymentElement",
                        stripe = Stripe(auctionSettingsData.stripePublicKey),
                        stripeElements = stripe.elements(options),
                        paymentElement = stripeElements.create("payment");
                    paymentElement.mount(stripeNode);
                    paymentElement.on("ready", function () {
                        $(nodeContainer).find("footer").removeClass(window.bs_data.hidden_class);
                    });
                    btnActionPaymentMethods(stripe, stripeElements);
                });
            } else {
                noticeSwall("error", "Unknown error", response.errorMessage);
                clearStripeForm();
            }
        }, function () {
        }, function () {
        });
    }

    /**
     * Detect Safari Private browsing mode
     * Returns a Promise that resolves to true if in private mode
     */
    function detectSafariPrivateMode() {
        return new Promise(function(resolve) {
            // Test localStorage access (throws in Safari Private)
            var testKey = 'paytrace_test';
            try {
                localStorage.setItem(testKey, testKey);
                localStorage.removeItem(testKey);
                // If we get here, not in private mode
                resolve(false);
            } catch(e) {
                // localStorage blocked = Safari Private
                resolve(true);
            }
        });
    }

    function loadPayTraceForm(apiAction, nodeContainer) {
        console.log('[PayTrace] === STARTING PAYMENT FORM LOAD ===');
        console.log('[PayTrace] Checking browser compatibility...');
        
        // Detect Safari Private mode first
        detectSafariPrivateMode().then(function(isPrivate) {
            if (isPrivate) {
                console.error('[PayTrace] Safari Private mode detected - PayTrace not supported');
                $(nodeContainer).find(".bs-loader-small").remove();
                noticeSwall(
                    "error",
                    "Browser Compatibility Issue",
                    "Safari Private browsing mode is not compatible with PayTrace. " +
                    "Please disable Private browsing mode or use Chrome/Firefox to add a payment method."
                );
                return; // Exit early
            }
            
            // Not in private mode, proceed normally
            console.log('[PayTrace] Browser compatible - proceeding');
            loadPayTraceFormInternal(apiAction, nodeContainer);
        });
    }

    function loadPayTraceFormInternal(apiAction, nodeContainer) {
        // BidSpirit call works directly from browser (has cookies)
        console.log('[PayTrace] Step 1: Calling BidSpirit API for clientSecret');
        console.log('[PayTrace] SessionId:', bidspiritSessionId);
        console.log('[PayTrace] API Action:', apiAction);
        
        // State tracking to prevent multiple error handlers
        var formLoadCompleted = false;
        var formLoadFailed = false;
        
        // Timeout fallback in case things hang
        var loadTimeout = setTimeout(function() {
            if (!formLoadCompleted && !formLoadFailed) {
                formLoadFailed = true;
                console.error('[PayTrace] TIMEOUT: Form load took too long (30s)');
                $(nodeContainer).find(".bs-loader-small").remove();
                noticeSwall("error", "Timeout", "Payment form failed to load. Please try again.");
            } else {
                console.log('[PayTrace] 30s timeout ignored - form already completed/failed');
            }
        }, 30000);
        
        bidspiritPostQuery(apiAction, {
            sessionId: bidspiritSessionId
        }, function (data) {
            console.log('[PayTrace] Step 2: BidSpirit API SUCCESS');
            console.log('[PayTrace] Response data:', data);
            $(nodeContainer).find('#payTracePaymentElement').append("<div id=\"pt_hpf_form\"></div>");
            if (data.response.clientSecret !== undefined) {
                console.log('[PayTrace] Step 3: Got clientSecret (length: ' + data.response.clientSecret.length + ')');
                console.log('[PayTrace] Step 4: Loading PayTrace SDK...');
                loadPayTraceSDK(function() {
                    console.log('[PayTrace] Step 5: SDK loaded successfully');
                    console.log('[PayTrace] Step 6: Calling PTPayment.setup (no interception - letting it run naturally)...');
                    
                    // Call PTPayment.setup without any interception
                    PTPayment.setup({
                        styles: getPayTraceStyles(),
                        authorization: {
                            clientKey: data.response.clientSecret 
                        }
                    }).then(function(instance) {
                        if (!formLoadCompleted && !formLoadFailed) {
                            formLoadCompleted = true;
                            clearTimeout(loadTimeout);
                            console.log('[PayTrace] Step 7: PTPayment.setup SUCCESS');
                            console.log('[PayTrace] Instance:', instance);
                            window.payTraceInstance = instance;
                            $(nodeContainer).find("footer").removeClass(window.bs_data.hidden_class);
                            $(nodeContainer).find(".bs-loader-small").remove();
                            console.log('[PayTrace] === FORM LOAD COMPLETE ===');
                            btnActionPayTracePaymentMethods();
                        }
                    }).catch(function(error) {
                        if (!formLoadCompleted && !formLoadFailed) {
                            formLoadFailed = true;
                            clearTimeout(loadTimeout);
                            console.error('[PayTrace] Step 7 FAILED: PTPayment.setup error');
                            console.error('[PayTrace] Error details:', error);
                            console.error('[PayTrace] Error stack:', error ? error.stack : 'no stack');
                            
                            // Restore original fetch/XHR
                            window.fetch = originalFetch;
                            XMLHttpRequest.prototype.open = originalOpen;
                            
                            $(nodeContainer).find(".bs-loader-small").remove();
                            
                            // Check if it's a timeout
                            if (error.message && error.message.indexOf('timed out') !== -1) {
                                noticeSwall("error", "Timeout", "PayTrace is incompatible with Safari Private browsing mode. Please use normal browsing or a different browser.");
                            } else {
                                noticeSwall("error", "Error", "Failed to initialize PayTrace form: " + error.message);
                            }
                        }
                    });
                });
            } else {
                if (!formLoadCompleted && !formLoadFailed) {
                    formLoadFailed = true;
                    clearTimeout(loadTimeout);
                    console.error('[PayTrace] Step 3 FAILED: No clientSecret in response');
                    console.error('[PayTrace] Response:', data);
                    $(nodeContainer).find(".bs-loader-small").remove();
                    noticeSwall("error", "Unknown error", data.response.errorMessage);
                }
            }
        }, function(error) {
            if (!formLoadCompleted && !formLoadFailed) {
                formLoadFailed = true;
                clearTimeout(loadTimeout);
                console.error('[PayTrace] Step 2 FAILED: BidSpirit API error callback');
                console.error('[PayTrace] Error:', error);
                $(nodeContainer).find(".bs-loader-small").remove();
                noticeSwall("error", "API Error", "Failed to connect to BidSpirit API");
            }
        });
    }

    function loadPayTraceSDK(callback) {
        var classTrigger = "paytrace-load";
        if (document.body.classList.contains(classTrigger)) {
            callback();
        } else {
            if (window.wp_data.sandbox === true) {
                console.info("We use sandbox envirement");
            }
            const sdkUrl = window.wp_data.sandbox === true
                ? "https://protect.sandbox.paytrace.com/js/protect.min.js"
                : "https://protect.paytrace.com/js/protect.min.js";

            console.log('[PayTrace] Fetching SDK from:', sdkUrl);
            $.getScript(sdkUrl)
                .done(function(script, textStatus) {
                    console.log('[PayTrace] SDK fetch done, status:', textStatus);
                    console.log('[PayTrace] PTPayment available:', typeof PTPayment !== 'undefined');
                    callback();
                    console.info(textStatus + " PayTrace SDK load");
                    document.body.classList.add(classTrigger);
                })
                .fail(function(jqxhr, settings, exception) {
                    console.error('[PayTrace] SDK LOAD FAILED');
                    console.error('[PayTrace] jqXHR:', jqxhr);
                    console.error('[PayTrace] Settings:', settings);
                    console.error('[PayTrace] Exception:', exception);
                    console.error('[PayTrace] Response text:', jqxhr.responseText);
                    $(nodeContainer).find(".bs-loader-small").remove();
                    noticeSwall("error", "Error", "Failed to load PayTrace SDK: " + exception);
                });
        }
    }

    function getPayTraceStyles() {
        var styles = {
            'cc': {
                'font_size': '16px',
                'input_border_radius': '2px',
                'input_border_width': '1px',
                'input_margin': '5px 0px 5px 0px',
                'input_padding': '3px 5px 3px 5px',
                'label_size': '14px',
                'label_width': '150px',
                'label_font_weight': 'bold',
                'label_margin': '5px 0px 0px 0px',
                'label_padding': '0px 5px 0px 5px',
                'background_color': 'white',
                'height': '25px',
                'width': '327px',
                'padding_bottom': '0px'
            },
            'code': {
                'border_color': '#333',
                'font_size': '13pt',
                'input_border_radius': '2px',
                'input_border_width': '1px',
                'input_margin': '5px 0px 5px 20px',
                'input_padding': '3px 5px 3px 5px',
                'background_color': 'white',
                'label_size': '14px',
                'label_width': '150px',
                'label_font_weight': 'bold',
                'label_margin': '5px 0px 0px 20px',
                'label_padding': '2px 5px 2px 5px',
                'height': '25px',
                'width': '110px',
                'padding_bottom': '2px'
            },
            'body': {
                'background_color': 'white'
            }
        }
        return styles;
    }

    function clearPayTraceForm() {
        var payTraceElement = $("#payTracePaymentElement");
        if (payTraceElement.length) {
            payTraceElement.empty().append('<div class="bs-loader-small"></div>');
        }
    }

    function btnActionPayTracePaymentMethods() {
        $("#addPaymentMethodAction").off("click").on("click", function () {
            var $this = $(this),
                modalContainer = $this.parents(".modal__container");
            modalContainer.append('<div class="bs-loader-fill"></div>');

            if (!window.payTraceInstance) {
                modalContainer.find(".bs-loader-fill").remove();
                noticeSwall("error", "Error", "PayTrace form not initialized");
                return;
            }

            window.payTraceInstance.process()
                .then(handlePayTraceCardSubmissionSuccess)
                .catch(handlePayTraceCardSubmissionError)
                .finally(function() {
                    modalContainer.find(".bs-loader-fill").remove();
                });
        });
    }

    function handlePayTraceCardSubmissionSuccess(encryptedCardInfo) {
        clearPayTraceForm();
        bidspiritQuery("users/paymentMethods/saveCardFromPayTrace", {
            sessionId: bidspiritSessionId,
            hpfToken: encryptedCardInfo.message.hpf_token,
            encKey: encryptedCardInfo.message.enc_key
        }, function (response) {
            clearPayTraceForm();
            if (!checkError(response)) {
                if (document.body.classList.contains('bp_profile_page')) {
                    showPaymentMethodsList();
                }

                paymentMethodList(function () {
                    if (!!paymentMethods[0]) {
                        let auction = document.querySelector("[data-auction-id]");
                        let data = {
                            sessionId: bidspiritSessionId,
                            paymentMethodId: paymentMethods[0].id
                        };

                        if (!!auction) {
                            data.auctionId = auction.getAttribute("data-auction-id");
                        }

                        bidspiritPostQuery("approvals/requestToParticipateInAuction", data, function (response) {
                            updateDisplay();
                        });
                    }
                });

                MicroModal.close("modal-payment-method");
                MicroModal.close("modal-request-approval");
            } else {
                console.log("handlePayTraceCardSubmissionError 1");
                handlePayTraceCardSubmissionError(response.error);
            }
        });
    }

    function handlePayTraceCardSubmissionError(error) {
        if (error !== undefined) {
            console.error("PayTrace submission error:", error);
        }
        clearPayTraceForm();
        loadPayTraceForm("users/paymentMethods/getPayTraceSetupSecret", $("#modal-payment-method").find(".modal__container"));
    }

    function togglePaymentForms(provider) {
        const stripForm = $("#stripePaymentElement");
        const payTraceForm = $("#payTracePaymentElement");
        
        if (provider === "PAY_TRACE") {
            stripForm.removeClass("active").addClass(window.bs_data.hidden_class);
            payTraceForm.addClass("active").removeClass(window.bs_data.hidden_class);
        } else {
            stripForm.addClass("active").removeClass(window.bs_data.hidden_class);
            payTraceForm.removeClass("active").addClass(window.bs_data.hidden_class);
        }
    }

    function addPaymentMethodCallback() {
        MicroModal.show("modal-payment-method", {
            onShow: function (modalBlock) {
                var $modalBlock = $("#modal-payment-method"),
                    footer = $modalBlock.find("footer");
                footer.find("#autoChargingCreditCardMessage-block").remove();
                footer.prepend('<p id="autoChargingCreditCardMessage-block" class="bp-text-red bp-mb-0">' + autoChargingCreditCardMessage(auctionSettingsData) + "</p>");
                
                togglePaymentForms(auctionSettingsData.creditCardProvider);
                
                if (auctionSettingsData.creditCardProvider === "PAY_TRACE") {
                    loadPayTraceForm("users/paymentMethods/getPayTraceSetupSecret", $modalBlock.find(".modal__container"));
                } else {
                    loadStripeForm("users/paymentMethods/getStripeSetupSecret", $modalBlock.find(".modal__container"));
                }
                
                $modalBlock.addClass(triggerClass);
            },
            onClose: function (modalBlock) {
                var $modalBlock = $(modalBlock);
                // $modalBlock.find(".modal__container").append('<div class="bs-loader-small"></div>');
                
                if (auctionSettingsData.creditCardProvider === "PAY_TRACE") {
                    clearPayTraceForm();
                } else {
                    clearStripeForm();
                }
                
                $modalBlock.find("footer").addClass(window.bs_data.hidden_class);
                $modalBlock.removeClass(triggerClass);
            }
        });
    }

    function paymentMethodAction(apiAction, container, bidspiritUser) {
        if (bidspiritUser !== undefined && bidspiritUser.approvalState === "INCOMPLETE_PROFILE") {
            loadTemplate(container, "account-empty-template", {
                message: window.bs_lang.access_denied
            });
        } else {
            loadTemplate(container, "payment-methods-template", {}, true, function () {
                $("#addPaymentMethod").on("click", addPaymentMethodCallback);
                showPaymentMethodsList();
            });
        }
    }

    function auctionInfoInit(bidspiritSessionId, currentAuctionNumber, callback) {
        if (currentAuctionNumber === "") {
            return false;
        } else {
            bidspiritQuery("auctions/getAuctionInfo", {
                sessionId: bidspiritSessionId,
                auctionId: currentAuctionNumber
            }, function (data) {
                if (!checkError(data)) {
                    bidspiritApi.setAuctionInfo(data.response);
                    var response = data.response;

                    if (response.approvalRequired !== undefined && response.approvalRequired) {
                        approvalInfo(currentAuctionNumber);
                    }

                    if (!!document.getElementById('auction-commission-field')) {
                        document.getElementById('auction-commission-field').textContent = data.response.commission + "%";
                    }
                }

                if (callback !== undefined) {
                    callback();
                }
            });
        }
    }

    function autoChargingCreditCardMessage(auctionSettingsData) {
        var additionalMessage = "";

        if (auctionSettingsData.autoPaymentDays !== undefined) {
            additionalMessage = window.bs_lang.auto_charge_x_days_after.replace(/#days#/, auctionSettingsData.autoPaymentDays);
        }

        return additionalMessage;
    }

    (function () {
        function loadMoreLots() {
            var triggerEvent = true,
                totalLots = catalogSection.attr("data-lot-count");
            $(window, ".st-content").scroll(function (event) {
                var st = $(this).scrollTop(),
                    wHeight = $(window).height(),
                    catalogSection = $("#catalog-section"),
                    catalogBlockHeight = catalogSection.height(),
                    catalogOffset = catalogSection.offset(),
                    endCatalog = catalogBlockHeight + catalogOffset.top,
                    midTriggerHeight = st + wHeight + 1000,
                    bgColor = catalogSection.attr("data-bg-color"),
                    count = catalogSection.find(".bp-lot").length,
                    part = catalogSection.attr("data-auction-part"),
                    loaderTemplate = $("#loadMore-template").html(),
                    lang = window.bs_data.lang;

                var sortBy = function () {
                    return searchGetParam("sort_by");
                };

                var categoryBy = function () {
                    return searchGetParam("category_by");
                };

                var phraseBy = function () {
                    return searchGetParam("phrase_by");
                };

                var perPage = function () {
                    return searchGetParam("per_page");
                };

                if (midTriggerHeight > endCatalog && triggerEvent && count < totalLots) {
                    catalogSection.append(loaderTemplate);
                    triggerEvent = false;
                    let currentAuctionNumber = catalogSection.attr("data-auction-index");
                    $.ajax({
                        type: "post",
                        dataType: "json",
                        url: window.wp_data.ajax_url,
                        data: {
                            action: "do_load_more",
                            security: window.wp_nonce,
                            auctionId: currentAuctionNumber,
                            termId: catalogSection.attr("data-term-id"),
                            count: count,
                            part: part,
                            lang: lang,
                            sort_by: sortBy(),
                            category_by: categoryBy(),
                            phrase_by: phraseBy(),
                            per_page: perPage()
                        }
                    }).done(function (response) {
                        var indexes = [];
                        $.each(response.data.lots, function (index, elem) {
                            indexes.push(elem.itemIndex);
                        });
                        loadTemplate(catalogSection, "lotsLoadMore-template", {
                            lots: response.data.lots,
                            currency: currencySymbol,
                            bgColor: bgColor,
                            showEstimatedPriceInItemsList: Boolean(parseInt(response.data.showEstimatedPriceInItemsList)),
                            displayStartPriceInCatalog: Boolean(parseInt(response.data.displayStartPriceInCatalog))
                        }, false, function () {
                        }, true);
                        count = catalogSection.find(".bp-lot").length;
                        totalLots = response.data.total;

                        new Promise((resolve, reject) => {
                            auctionInfoInit(bidspiritSessionId, currentAuctionNumber, resolve);
                            // resolve();
                        }).then(function (response) {
                            updateAuctionPage(catalogSection, indexes);
                        });

                        triggerEvent = true;
                    }).fail(function () {
                        console.error("Fatal error");
                    }).always(function () {
                        $("#bsLoaderCatalog").remove();
                    });
                }
            });
        }

        var catalogSection = $("#catalog-section"),
            pagination = window.bs_data.use_pagination;

        if (catalogSection.length && pagination === "off") {
            loadMoreLots();
        }
    })();

    function updateDisplay() {
        var singleLot = $("#single-lot"),
            catalogSection = $("#catalog-section"),
            profile = $("#profile-page");

        (function () {
            if (catalogSection.length) {
                var currentAuctionNumber = catalogSection.attr("data-auction-id");

                new Promise((resolve, reject) => {
                    auctionInfoInit(bidspiritSessionId, currentAuctionNumber, resolve);
                }).then(function (response) {
                    updateAuctionPage(catalogSection);
                    toggleAuctionAlert(currentAuctionNumber);
                });
            }
        })();

        (function () {
            if (singleLot.length) {
                var lot = $("#single-lot"),
                    dateTime = $("#dateTimeField"),
                    fullPriceNode = $("#bp-fullPrice");
                currentLotIndex = lot.attr("data-lot-index");
                currentAuctionNumber = lot.attr("data-auction-index");

                new Promise((resolve, reject) => {
                    auctionInfoInit(bidspiritSessionId, currentAuctionNumber, resolve);
                }).then(function (response) {
                    loadBid(currentLotIndex, currentAuctionNumber);
                });

                if (dateTime.length) {
                    getLeftDate(dateTime.attr("data-time"));
                }
            }
        })();

        (function () {
            function profileQuery(apiAction, lotList) {
                // Use the paginated function with future/past toggle for all profile tabs
                if (apiAction === "account/getAbsenteeBids" ||
                    apiAction === "account/getFavorites" ||
                    apiAction === "account/getPurchases") {
                    profilePaginatedQuery(apiAction, lotList);
                    return;
                }
                bidspiritQuery(apiAction, {
                    sessionId: bidspiritSessionId,
                    language: LANG
                }, function (data) {
                    if (data.response.count > 0) {
                        loadTemplate(lotList, "account-items-template", {
                            items: data.response.items,
                            currency: currencySymbol,
                            imageBlank: imageBlank,
                            bgColor: $("#profile-page").attr("data-bg-color")
                        }, false, function () {
                            $(lotList + " .bp-lots .bp-lot").each(function (index, elem) {
                                var $this = $(elem),
                                    wishBtn = $this.find(".bp__wishlist");
                                $this.find("a").on("click", function (event) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                    $.ajax({
                                        type: "post",
                                        dataType: "json",
                                        url: window.wp_data.ajax_url,
                                        data: {
                                            action: "do_link",
                                            security: window.wp_nonce,
                                            bidSpirit: {
                                                lot_id: $this.attr("data-lot-id")
                                            }
                                        }
                                    }).done(function (response) {
                                        if (response.data !== undefined && response.success === true) {
                                            window.location = response.data.link;
                                        } else {
                                            noticeSwall("error", window.bs_lang.not_found);
                                        }
                                    }).fail(function (response) {
                                        noticeSwall("error", window.bs_lang.not_found);
                                    });
                                });
                                wishBtn.on("click", function (event) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                    toggleFavorite($this, wishBtn, $this.attr("data-auction-number"), true);
                                });
                            });

                            data.response.items.forEach(function (lot) {
                                if (lot.item.id !== undefined) {
                                    let elem = $("[data-lot-id=\"" + lot.item.id + "\"]");
                                    if (elem.length > 0) {
                                        let $this = $(elem);

                                        var nextMinBid = 0;
                                        nextMinBid = getMinBidPriceFromIncrementSteps(lot, lot.auction.increments);
                                        initIncrementSteps(lot.auction.increments, nextMinBid);
                                        let incrementStepsList = allIncrementsPrices;

                                        let bids = [];
                                        Array.prototype.forEach.call(incrementStepsList, function (elem, i) {
                                            if (elem >= nextMinBid) {
                                                bids.push({
                                                    id: elem,
                                                    text: formattedPrice(elem, currencySymbol)
                                                });
                                            }
                                        });

                                        if (bids.length > 0 && bids[0] !== undefined && bids[0].id !== undefined && (nextMinBid !== 0 && nextMinBid < bids[0].id)) {
                                            bids.unshift({
                                                id: nextMinBid,
                                                text: formattedPrice(nextMinBid, currencySymbol)
                                            });
                                        }

                                        console.log($this);
                                        let selectBid = select2build($this.find(".js-data-bid-list"), bids);
                                    }
                                }
                            });
                        });
                    } else {
                        loadTemplate(lotList, "account-empty-template", {
                            message: "Lot list empty"
                        });
                    }
                }, function (data) {
                    noticeSwall("error", "The request failed", "Your account may have been logged in earlier.");
                });
            }

            /**
             * Generic paginated profile query with Future / Ended auction toggle.
             * Handles BidSpirit's 1000-item API limit by fetching additional pages.
             * Works for: getAbsenteeBids, getFavorites, getPurchases
             */
            function profilePaginatedQuery(apiAction, lotList) {
                var API_PAGE_SIZE = 1000;
                var allCollectedItems = [];
                // Generate unique section IDs based on the API action to avoid conflicts
                var sectionPrefix = "bp-paginated-" + apiAction.replace(/\//g, "-");
                var futureId = sectionPrefix + "-future";
                var endedId = sectionPrefix + "-ended";

                // Show loading indicator
                $(lotList).html('<div class="bp-row bp-fix-width-lot"><div class="bp-d-flex bp-f-wrap bp-f-center bp-mb-30"><p>Loading...</p></div></div>');

                /**
                 * Fetch a page of items starting at the given offset.
                 * If 1000 items are returned (= page limit hit), fetch the next page.
                 */
                function fetchPage(offset) {
                    var params = {
                        sessionId: bidspiritSessionId,
                        language: LANG
                    };
                    if (offset > 0) {
                        params.offset = offset;
                    }

                    console.log("[Profile:" + apiAction + "] Fetching page, offset=" + offset);

                    bidspiritQuery(apiAction, params, function (data) {
                        console.log("[Profile:" + apiAction + "] Page response (offset=" + offset + "):", "count=" + data.response.count, "items=" + (data.response.items ? data.response.items.length : 0));

                        if (data.response.items && data.response.items.length > 0) {
                            allCollectedItems = allCollectedItems.concat(data.response.items);
                            console.log("[Profile:" + apiAction + "] Total collected so far:", allCollectedItems.length);

                            if (data.response.items.length >= API_PAGE_SIZE) {
                                $(lotList).html('<div class="bp-row bp-fix-width-lot"><div class="bp-d-flex bp-f-wrap bp-f-center bp-mb-30"><p>Loading... (' + allCollectedItems.length + ' loaded)</p></div></div>');
                                fetchPage(offset + API_PAGE_SIZE);
                                return;
                            }
                        }

                        if (allCollectedItems.length > 0) {
                            renderAllItems(allCollectedItems);
                        } else {
                            loadTemplate(lotList, "account-empty-template", {
                                message: "Lots not found"
                            });
                        }
                    }, function (data) {
                        if (allCollectedItems.length > 0) {
                            console.warn("[Profile:" + apiAction + "] Page fetch failed at offset=" + offset + ", rendering " + allCollectedItems.length + " items collected so far");
                            renderAllItems(allCollectedItems);
                        } else {
                            console.error("[Profile:" + apiAction + "] API request failed:", data);
                            noticeSwall("error", "The request failed", "Your account may have been logged in earlier.");
                        }
                    });
                }

                /**
                 * Split items into future/ended and render with toggle buttons.
                 */
                function renderAllItems(allItems) {
                    console.log("[Profile:" + apiAction + "] Rendering all items, total:", allItems.length);

                    var auctionDates = {};
                    allItems.forEach(function(lot) {
                        var key = lot.auction.date || 'unknown';
                        if (!auctionDates[key]) auctionDates[key] = 0;
                        auctionDates[key]++;
                    });
                    console.log("[Profile:" + apiAction + "] Auction dates breakdown:", auctionDates);

                    var futureItems = [];
                    var endedItems = [];

                    allItems.forEach(function(lot) {
                        var isEnded = false;
                        if (lot.item.wasInLiveAuction === true) {
                            isEnded = true;
                        } else if (lot.soldBid !== undefined && lot.soldBid.isSold === true) {
                            isEnded = true;
                        } else if (lot.leadingBid !== undefined && lot.leadingBid.isSold === true) {
                            isEnded = true;
                        }

                        if (isEnded) {
                            endedItems.push(lot);
                        } else {
                            futureItems.push(lot);
                        }
                    });

                    console.log("[Profile:" + apiAction + "] Future items:", futureItems.length, "Ended items:", endedItems.length);

                    var toggleHtml = '<div class="bp-bids-toggle-wrapper" style="text-align: center; padding: 15px 0 5px;">';
                    toggleHtml += '<button type="button" class="bp-bids-toggle-btn bp-bids-toggle-active" data-target="future">Future Auctions (' + futureItems.length + ')</button>';
                    toggleHtml += '<button type="button" class="bp-bids-toggle-btn" data-target="ended">Ended Auctions (' + endedItems.length + ')</button>';
                    toggleHtml += '</div>';
                    toggleHtml += '<div id="' + futureId + '"></div>';
                    toggleHtml += '<div id="' + endedId + '" style="display:none;"></div>';

                    $(lotList).html(toggleHtml);

                    function renderSectionItems(targetSelector, items) {
                        if (items.length === 0) {
                            $(targetSelector).html('<div class="bp-row bp-fix-width-lot"><div class="bp-d-flex bp-f-wrap bp-f-center bp-mb-30"><p>Lots not found</p></div></div>');
                            return;
                        }
                        loadTemplate(targetSelector, "account-items-template", {
                            items: items,
                            currency: currencySymbol,
                            imageBlank: imageBlank,
                            bgColor: $("#profile-page").attr("data-bg-color")
                        }, false, function () {
                            $(targetSelector + " .bp-lots .bp-lot").each(function (index, elem) {
                                var $this = $(elem),
                                    wishBtn = $this.find(".bp__wishlist");
                                $this.find("a").on("click", function (event) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                    $.ajax({
                                        type: "post",
                                        dataType: "json",
                                        url: window.wp_data.ajax_url,
                                        data: {
                                            action: "do_link",
                                            security: window.wp_nonce,
                                            bidSpirit: {
                                                lot_id: $this.attr("data-lot-id")
                                            }
                                        }
                                    }).done(function (response) {
                                        if (response.data !== undefined && response.success === true) {
                                            window.location = response.data.link;
                                        } else {
                                            noticeSwall("error", window.bs_lang.not_found);
                                        }
                                    }).fail(function (response) {
                                        noticeSwall("error", window.bs_lang.not_found);
                                    });
                                });
                                wishBtn.on("click", function (event) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                    toggleFavorite($this, wishBtn, $this.attr("data-auction-number"), true);
                                });
                            });

                            items.forEach(function (lot) {
                                if (lot.item.id !== undefined) {
                                    var elem = $(targetSelector + " [data-lot-id=\"" + lot.item.id + "\"]");
                                    if (elem.length > 0) {
                                        var $this = $(elem);
                                        var nextMinBid = 0;
                                        nextMinBid = getMinBidPriceFromIncrementSteps(lot, lot.auction.increments);
                                        initIncrementSteps(lot.auction.increments, nextMinBid);
                                        var incrementStepsList = allIncrementsPrices;

                                        var bids = [];
                                        Array.prototype.forEach.call(incrementStepsList, function (elem, i) {
                                            if (elem >= nextMinBid) {
                                                bids.push({
                                                    id: elem,
                                                    text: formattedPrice(elem, currencySymbol)
                                                });
                                            }
                                        });

                                        if (bids.length > 0 && bids[0] !== undefined && bids[0].id !== undefined && (nextMinBid !== 0 && nextMinBid < bids[0].id)) {
                                            bids.unshift({
                                                id: nextMinBid,
                                                text: formattedPrice(nextMinBid, currencySymbol)
                                            });
                                        }

                                        select2build($this.find(".js-data-bid-list"), bids);
                                    }
                                }
                            });
                        });
                    }

                    renderSectionItems("#" + futureId, futureItems);
                    renderSectionItems("#" + endedId, endedItems);

                    $(lotList).on("click", ".bp-bids-toggle-btn", function () {
                        var target = $(this).attr("data-target");
                        $(lotList).find(".bp-bids-toggle-btn").removeClass("bp-bids-toggle-active");
                        $(this).addClass("bp-bids-toggle-active");
                        if (target === "future") {
                            $("#" + futureId).show();
                            $("#" + endedId).hide();
                        } else {
                            $("#" + futureId).hide();
                            $("#" + endedId).show();
                        }
                    });
                }

                // Start fetching from offset 0
                fetchPage(0);
            }

            function buildFields(user) {
                function checkField(field) {
                    return field !== undefined ? field : "";
                }

                let settings = bidspiritApi.getAuctionSettingsData();

                var fields = {
                    honorific: {
                        value: checkField(user.honorific),
                        label: "Honorific",
                        required: false,
                        type: "text"
                    },
                    firstName: {
                        value: checkField(user.firstName),
                        label: "First Name",
                        required: true,
                        type: "text"
                    },
                    lastName: {
                        value: checkField(user.lastName),
                        label: "Last Name",
                        required: true,
                        type: "text"
                    },
                    email: {
                        value: checkField(user.email),
                        label: "Email",
                        required: true,
                        type: "email"
                    },
                    password: {
                        value: "",
                        label: "Password",
                        required: false,
                        type: "password"
                    },
                    phone: {
                        value: checkField(user.phone),
                        label: "Phone",
                        required: true,
                        type: "phone"
                    },
                    secondPhone: {
                        value: checkField(user.secondPhone),
                        label: "Second phone",
                        required: false,
                        type: "phone"
                    },
                    id: {
                        value: checkField(user.id),
                        label: "ID",
                        required: false,
                        type: "text",
                        idPhotoUploadRequired: settings.idPhotoUploadRequired,
                        requireIdPhoto: settings.requireIdPhoto,
                        missingIdPhoto: bidspiritUser.missingIdPhoto,
                        hasIdPhoto: bidspiritUser.hasIdPhoto
                    },
                    taxNumber: {
                        value: checkField(user.taxNumber),
                        label: "Tax number",
                        required: false,
                        type: "text"
                    }
                },
                fieldsAddress = {
                    countryCode: {
                        value: "",
                        label: "Country",
                        required: true,
                        type: "select"
                    },
                    state: {
                        value: "",
                        label: "State",
                        required: false,
                        type: "select",
                        hidden: true
                    },
                    province: {
                        value: "",
                        label: "State",
                        required: false,
                        type: "text",
                        hidden: true
                    },
                    city: {
                        value: "",
                        label: "City",
                        required: true,
                        type: "text"
                    },
                    address: {
                        value: "",
                        label: "Address",
                        required: true,
                        type: "text"
                    },
                    zipCode: {
                        value: "",
                        label: "Zip Code",
                        required: true,
                        type: "text"
                    }
                };

                if (user.address !== undefined) {
                    fieldsAddress = {
                        countryCode: {
                            value: checkField(user.address.countryCode),
                            label: "Country",
                            required: true,
                            type: "select"
                        },
                        state: {
                            value: checkField(user.address.state),
                            label: "State",
                            required: false,
                            type: "select",
                            hidden: true
                        },
                        province: {
                            value: checkField(user.address.state),
                            label: "State",
                            required: false,
                            type: "text",
                            hidden: true
                        },
                        city: {
                            value: checkField(user.address.city),
                            label: "City",
                            required: true,
                            type: "text"
                        },
                        address: {
                            value: checkField(user.address.address),
                            label: "Address",
                            required: true,
                            type: "text"
                        },
                        zipCode: {
                            value: checkField(user.address.zipCode),
                            label: "Zip Code",
                            required: true,
                            type: "text"
                        }
                    };
                }

                return $.extend(fields, fieldsAddress);
            }

            function buildShippingFields(user) {
                function checkField(field) {
                    return field !== undefined ? field : "";
                }

                var shippingFields = {
                    recipientName: {
                        value: "",
                        label: "Recipient name",
                        required: false,
                        type: "text"
                    },
                    countryCode: {
                        value: "",
                        label: "Country",
                        required: true,
                        type: "select"
                    },
                    state: {
                        value: "",
                        label: "State",
                        required: false,
                        type: "select",
                        hidden: true
                    },
                    province: {
                        value: "",
                        label: "State",
                        required: false,
                        type: "text",
                        hidden: true
                    },
                    city: {
                        value: "",
                        label: "City",
                        required: true,
                        type: "text"
                    },
                    address: {
                        value: "",
                        label: "Address",
                        required: true,
                        type: "text"
                    },
                    zipCode: {
                        value: "",
                        label: "Zip Code",
                        required: true,
                        type: "text"
                    }
                };

                if (user.shipping !== undefined) {
                    shippingFields = {
                        recipientName: {
                            value: checkField(user.shipping.recipientName),
                            label: "Recipient name",
                            required: false,
                            type: "text"
                        },
                        countryCode: {
                            value: checkField(user.shipping.countryCode),
                            label: "Country",
                            required: true,
                            type: "select"
                        },
                        state: {
                            value: checkField(user.shipping.state),
                            label: "State",
                            required: false,
                            type: "select",
                            hidden: true
                        },
                        province: {
                            value: checkField(user.shipping.state),
                            label: "State",
                            required: false,
                            type: "text",
                            hidden: true
                        },
                        city: {
                            value: checkField(user.shipping.city),
                            label: "City",
                            required: true,
                            type: "text"
                        },
                        address: {
                            value: checkField(user.shipping.address),
                            label: "Address",
                            required: true,
                            type: "text"
                        },
                        zipCode: {
                            value: checkField(user.shipping.zipCode),
                            label: "Zip Code",
                            required: true,
                            type: "text"
                        }
                    };
                }

                return shippingFields;
            }

            function profileFormAction() {
                var profileSection = "#profile-account-section";

                function uploadIdPhotoAction() {
                    $('#uploadPhotoIdAction').off('click').on('click', function (event) {
                        if (!$("#uploadIdPhotoInput").val()){
                            noticeSwall("error", window.bs_lang.select_file_to_upload);
                            return;
                        }
                        let $this = $(this);
                        $this.prop("disabled", true);
                        var formData = new FormData();
                        formData.append("file", $("#uploadIdPhotoInput")[0].files[0])

                        $.ajax({
                            url: BIDSPIRIT_API_BASE + "users/idphoto/setUserIdPhoto.api?sessionId="+bidspiritSessionId,
                            headers: {
                                'BIDSPIRIT-AUTH-TOKEN': bidspiritApi.getAuthToken('users/idphoto/setUserIdPhoto'),
                            },
                            type: 'POST',
                            data: formData,
                            cache: false,
                            contentType: false,
                            processData: false,
                        })
                        .done(function(data) {
                            if (!checkError(data)) {
                                $("#uploadIdPhotoButton").prop({disabled:false});
                                bidspiritUser.hasIdPhoto = true;
                                noticeSwall("info", window.bs_lang.photo_id_uploaded_successfully);
                                updateIdPhotoUploadDisplay();
                            }
                        })
                        .fail(function() {
                            console.error("error");
                        })
                        .always(function() {
                            $this.prop("disabled", false);
                        });
                    })
                }

                function displayIdPhoto(button){
                    MicroModal.init(microModalInitConfig());
                    $.ajax({
                        url: BIDSPIRIT_API_BASE + "users/idphoto/getUserIdPhoto.api?sessionId=" + bidspiritSessionId,
                        headers: {
                            'BIDSPIRIT-AUTH-TOKEN': bidspiritApi.getAuthToken('users/idphoto/getUserIdPhoto'),
                        },
                        xhrFields: {
                            responseType: 'blob'
                        }
                    })
                    .done(function(data) {
                        var url = URL.createObjectURL(data);
                        $('#idPhotoImage').attr('src', url);
                        MicroModal.show("modal-photoId", microModalInitConfig());
                    })
                    .fail(function() {
                        console.error("error displayIdPhoto");
                    })
                    .always(function() {
                        $(button).prop("disabled", false);
                    });
                }

                function updateIdPhotoUploadDisplay(){
                    if (bidspiritUser && (!bidspiritUser.hasIdPhoto)) {
                        $("#uploadIdPhotoSection").show();
                        $("#deleteIdPhotoSection").hide();

                        if (auctionSettingsData.idPhotoUploadRequired) {
                            $('#uploadIdPhotoInput').prop("required", true);
                        }
                    } else {
                        $("#uploadIdPhotoSection").hide();
                        $("#deleteIdPhotoSection").show();
                    }
                }

                function deleteIdPhoto(button){
                    Swal.fire({
                        title: window.bs_lang.you_want_to_remove_your_id_photo,
                        showDenyButton: true,
                        showCancelButton: true,
                        confirmButtonText: window.bs_lang.yes,
                        denyButtonText: window.bs_lang.cancel
                    }).then((result) => {
                        if (result.isConfirmed) {
                            bidspiritPostQuery("users/idphoto/removeUserIdPhoto", {
                                sessionId: bidspiritSessionId
                            }, (data) => {
                                if (!checkError(data)) {
                                    bidspiritUser.hasIdPhoto = false;
                                    noticeSwall("info", window.bs_lang.id_photo_deleted);
                                }

                                updateIdPhotoUploadDisplay();
                            }, () => {}, () => {
                                $(button).prop("disabled", false);
                            });
                        } else if (result.isDenied) {

                        }
                    });
                }

                function codeFieldList(bidspiritUser) {
                    bidspiritQuery("settings/getCountriesList", {
                        sessionId: bidspiritSessionId,
                        language: LANG
                    }, function (data) {
                        var countrySelect = $("#profilecountryCode"),
                            countryShippingSelect = $("#shippingcountryCode"),
                            stateSelect = $("#profilestate"),
                            stateShippingSelect = $("#shippingFieldstate"),
                            provinceShippingSelect = $("#shippingFieldprovince"),
                            codeSelect = $(".phoneCodeSelect"),
                            codeFirstSelect = $("#detailsphoneCountryCode"),
                            codeSecondSelect = $("#detailssecondPhoneCountryCode"),
                            items = [],
                            codeItems = [];

                        if (data.response !== undefined) {
                            items = $.map(data.response, function (obj) {
                                return {
                                    id: obj.code,
                                    phoneCode: obj.phoneCode,
                                    text: obj.name
                                };
                            });
                            codeItems = $.map(data.response, function (obj) {
                                if (obj.phoneCode !== undefined) {
                                    return {
                                        id: obj.phoneCode,
                                        text: obj.phoneCode + " (" + obj.name + ")"
                                    };
                                }
                            });
                        }

                        countrySelect.select2({
                            theme: "default bp-custom-select",
                            width: "resolve",
                            data: items
                        });
                        countryShippingSelect.select2({
                            theme: "default bp-custom-select",
                            width: "resolve",
                            data: items
                        });

                        if (bidspiritUser.address !== undefined && bidspiritUser.address.countryCode !== undefined) {
                            countrySelect.val(bidspiritUser.address.countryCode).trigger("change.select2");

                            if (bidspiritUser.address.countryCode !== "US") {
                                stateSelect.val("").trigger("change.select2");
                            }
                        }
                        if (bidspiritUser.shipping !== undefined && bidspiritUser.shipping.countryCode !== undefined) {
                            countryShippingSelect.val(bidspiritUser.shipping.countryCode).trigger("change.select2");

                            if (bidspiritUser.shipping.countryCode !== "US") {
                                countryShippingSelect.val("").trigger("change.select2");
                            }
                        }

                        countrySelect.on("select2:select", function (event) {
                            var data = event.params.data;
                            fieldState(data.id, "");
                            fieldTaxNumber();
                        });
                        countryShippingSelect.on("select2:select", function (event) {
                            var data = event.params.data;
                            fieldShippingFields(data.id, "");
                        });
                        codeSelect.select2({
                            theme: "default bp-custom-select",
                            width: "resolve",
                            data: codeItems,
                            placeholder: window.bs_lang.country_code
                        });

                        if (bidspiritUser.phoneCountryCode !== undefined) {
                            codeFirstSelect.val(bidspiritUser.phoneCountryCode).trigger("change.select2");
                        }

                        if (bidspiritUser.secondPhoneCountryCode !== undefined) {
                            codeSecondSelect.val(bidspiritUser.secondPhoneCountryCode).trigger("change.select2");
                        }

                        stateList(bidspiritUser);

                        if (countrySelect.val() === "US") {
                            stateSelect.parents(".bp-form-group").removeClass(window.bs_data.hidden_class);
                        }
                        if (countryShippingSelect.val() === "US") {
                            stateShippingSelect.parents(".bp-form-group").removeClass(window.bs_data.hidden_class);
                        }
                        if (countryShippingSelect.val() !== "US" && countryShippingSelect.val() !== "IL") {
                            provinceShippingSelect.removeClass(window.bs_data.hidden_class);
                        }
                    });
                }

                function fieldState(stateCode, value) {
                    var stateSelect = $("#profilestate"),
                        provinceField = $("#profileprovince"),
                        stateCodeUS = "US",
                        stateCodeIL = "IL";

                    if (stateCode === stateCodeUS) {
                        provinceField.parents(".bp-form-group").addClass(window.bs_data.hidden_class);
                        provinceField.attr("name", "province");
                        stateSelect.parents(".bp-form-group").removeClass(window.bs_data.hidden_class);

                        if (bidspiritUser.address !== undefined && bidspiritUser.address.stateCode !== undefined && value !== "") {
                            stateSelect.val(bidspiritUser.address.stateCode).trigger("change.select2");
                        }
                    } else if (stateCode === stateCodeIL) {
                        stateSelect.parents(".bp-form-group").addClass(window.bs_data.hidden_class);
                        provinceField.parents(".bp-form-group").addClass(window.bs_data.hidden_class);
                        provinceField.attr({
                            name: "state",
                            value: ""
                        });
                    } else {
                        provinceField.parents(".bp-form-group").removeClass(window.bs_data.hidden_class);
                        provinceField.attr({
                            name: "state",
                            value: value
                        });
                        stateSelect.parents(".bp-form-group").addClass(window.bs_data.hidden_class);
                    }
                }

                function fieldShippingFields(stateCode, value) {
                    var stateSelect = $("#shippingstate"),
                        countryField = $("#shippingcountryCode"),
                        provinceField = $("#shippingprovince"),
                        stateCodeUS = "US",
                        stateCodeIL = "IL";

                    if (bidspiritUser.shipping !== undefined && bidspiritUser.shipping.countryCode !== undefined && stateCode !== "") {
                        countryField.val(stateCode).trigger("change.select2");
                    }

                    if (stateCode === stateCodeUS) {
                        provinceField.parents(".bp-form-group").addClass(window.bs_data.hidden_class);
                        provinceField.attr("name", "shipping.province");
                        stateSelect.parents(".bp-form-group").removeClass(window.bs_data.hidden_class);

                        if (bidspiritUser.shipping !== undefined && bidspiritUser.shipping.state !== undefined && value !== "") {
                            stateSelect.val(bidspiritUser.shipping.state).trigger("change.select2");
                        }
                    } else if (stateCode === stateCodeIL) {
                        stateSelect.parents(".bp-form-group").addClass(window.bs_data.hidden_class);
                        provinceField.parents(".bp-form-group").addClass(window.bs_data.hidden_class);
                        provinceField.attr({
                            name: "shipping.state",
                            value: ""
                        });
                    } else {
                        provinceField.parents(".bp-form-group").removeClass(window.bs_data.hidden_class);
                        provinceField.attr({
                            name: "shipping.state",
                            value: value
                        });
                        stateSelect.parents(".bp-form-group").addClass(window.bs_data.hidden_class);

                        if (bidspiritUser.shipping !== undefined && bidspiritUser.shipping.countryCode !== undefined && value !== "") {
                            countryField.val(bidspiritUser.shipping.countryCode).trigger("change.select2");
                        }
                    }
                }

                function fieldTaxNumber() {
                    var taxNumberField = $("#profiletaxNumber"),
                        bsOptions = window.bs_data;

                    if (bsOptions.tax_number_required !== undefined && bsOptions.tax_number_required === "on") {
                        taxNumberField.parents(".bp-form-group").removeClass(window.bs_data.hidden_class);
                        taxNumberField.attr("required", "true").attr("placeholder", taxNumberField.attr("placeholder") + " *");
                    } else {
                        taxNumberField.parents(".bp-form-group").addClass(window.bs_data.hidden_class);
                        taxNumberField.val("").removeAttr("required");
                    }
                }

                function stateList(bidspiritUser) {
                    var stateCodeUS = "US";
                    bidspiritQuery("settings/getCountryStates", {
                        sessionId: bidspiritSessionId,
                        countryCode: stateCodeUS
                    }, function (data) {
                        var countrySelect = $("#profilecountryCode"),
                            stateSelect = $("#profilestate"),
                            stateShippingSelect = $("#shippingstate"),
                            items = [];

                        if (data.response !== undefined) {
                            data.response.unshift({
                                code: "",
                                name: ""
                            });
                            items = $.map(data.response, function (obj) {
                                return {
                                    id: obj.code,
                                    text: obj.name
                                };
                            });
                        }

                        stateSelect.select2({
                            theme: "default bp-custom-select",
                            width: "resolve",
                            data: items,
                            placeholder: "State"
                        });
                        stateShippingSelect.select2({
                            theme: "default bp-custom-select",
                            width: "resolve",
                            data: items,
                            placeholder: "State"
                        });

                        var stateVal = "";

                        if (bidspiritUser.address !== undefined && (bidspiritUser.address.state !== undefined || bidspiritUser.address.stateCode !== undefined)) {
                            stateVal = bidspiritUser.address.state;

                            if (bidspiritUser.address.countryCode === "US") {
                                stateVal = bpIsset(bidspiritUser.address.stateCode) ? bidspiritUser.address.stateCode : bidspiritUser.address.state;
                            }

                            fieldState(countrySelect.val(), stateVal);
                        }

                        if (bidspiritUser.shipping !== undefined && (bidspiritUser.shipping.state !== undefined || bidspiritUser.shipping.stateCode !== undefined)) {
                            stateVal = bidspiritUser.shipping.state;

                            /*if (bidspiritUser.shipping.countryCode === "US") {
                                stateVal = bpIsset(bidspiritUser.shipping.stateCode) ? bidspiritUser.shipping.stateCode : bidspiritUser.shipping.state;
                            }*/

                            fieldShippingFields(bidspiritUser.shipping.countryCode, stateVal);
                        }

                        fieldTaxNumber();
                    });
                }

                if (!$(profileSection + " > *").length) {
                    let profileJsTemplate = "profile-account-template";
                    if (!!document.getElementById("profile-account-v2-template")) {
                        profileJsTemplate = "profile-account-v2-template";
                    }

                    loadTemplate(profileSection, profileJsTemplate, {
                        user: bidspiritUser,
                        fields: buildFields(bidspiritUser),
                        shippingFields: buildShippingFields(bidspiritUser),
                        stateInfo: getApprovalStateInfo(bidspiritUser)
                    }, true, function () {
                        if (bidspiritUser.allowInvitations !== undefined) {
                            $(subscribeCheckbox).prop("checked", bidspiritUser.allowInvitations);
                        }

                        $(subscribeCheckbox).on("change", function (event) {
                            var $this = $(this),
                                value = $this.prop("checked");
                            setInvitationsEnabled(value);
                        });

                        updateIdPhotoUploadDisplay();

                        if (!!document.getElementById('uploadPhotoIdAction') && !!document.getElementById('uploadIdPhotoInput')) {
                            uploadIdPhotoAction();
                        }

                        if (!!document.getElementById('showIdPhoto') && !!document.getElementById('deleteIdPhoto')) {
                            $('#showIdPhoto').off('click').on('click', function (event) {
                                event.preventDefault();
                                $(event.target).prop("disabled", true);
                                displayIdPhoto(event.target);
                            });
                            $('#deleteIdPhoto').off('click').on('click', function (event) {
                                event.preventDefault();
                                $(event.target).prop("disabled", true);
                                deleteIdPhoto(event.target);
                            });
                        }
                    });

                    codeFieldList(bidspiritUser);

                }

                let profileEmailEditSelector = "#profileemail + svg.icon";

                if ($(profileEmailEditSelector).length !== 0) {
                    $(profileEmailEditSelector).off('click').on("click", function (event) {
                        document.getElementById("profileemail").disabled = false;
                    });
                }

                passwordShowAction();
            }

            if (profile.length) {
                var wishList = "#bp-wish-list",
                    wishListSection = "#profile-wishlist-section",
                    bidsList = "#bp-my-bids",
                    bidsListSection = "#profile-bids-section",
                    winningsList = "#bp-winnings",
                    winningsListSection = "#profile-winnings-section",
                    billsList = "#bp-bills",
                    billsListSection = "#profile-bills-section",
                    paymentMethods = "#bp-payment-methods",
                    paymentMethodsSection = "#profile-payment-methods-section",
                    subscribeCheckbox = "#invitationsEnabled input";

                if (bidspiritUser && bidspiritUser.emailConfirmed === true) {
                    loadTemplate("#profile-page", "profile-page-template", bidspiritUser, false, function () {
                        activeTabs();

                        switch (window.location.hash) {
                            case wishList:
                                profileQuery("account/getFavorites", wishListSection);
                                break;

                            case bidsList:
                                profileQuery("account/getAbsenteeBids", bidsListSection);
                                break;

                            case winningsList:
                                profileQuery("account/getPurchases", winningsListSection);
                                break;

                            case billsList:
                                billsAction(billsListSection);
                                break;

                            case paymentMethods:
                                paymentMethodAction("users/paymentMethods/getStripeSetupSecret", paymentMethodsSection, bidspiritUser);
                                break;

                            default:
                                profileFormAction();
                        }
                    });
                } else if (bidspiritUser && bidspiritUser.emailConfirmed === false) {
                    loadTemplate("#profile-page", "profile-page-empty-template", bidspiritUser);
                } else {
                    loadTemplate("#profile-page", "profile-page-gate-template", bidspiritUser);
                    MicroModal.init(microModalInitConfig());
                }

                var updateDetailsForm = $("#updateDetailsSection"),
                    logoutAction = $(".logoutLink"),
                    shippingAction = $("#profileShippingCheckbox"),
                    shippingWrapper = $("#wrpShippingField"),
                    profileLink = $("#bp-profile-link, #bp-account .bp-spoiler-trigger"),
                    wishListLink = $("#bp-wish-list-link, #bp-wish-list .bp-spoiler-trigger"),
                    bidsListLink = $("#bp-bids-list-link, #bp-my-bids .bp-spoiler-trigger"),
                    paymentMethodsLink = $("#bp-payment-methods-link, #bp-payment-methods .bp-spoiler-trigger"),
                    winningsListLink = $("#bp-winnings-list-link, #bp-winnings .bp-spoiler-trigger"),
                    billsListLink = $("#bp-bills-link, #bp-bills .bp-spoiler-trigger");

                if (updateDetailsForm.length) {
                    updateDetailsForm.on("submit", function (event) {
                        event.preventDefault();
                        submitUpdateDetails();
                    });

                    if (shippingAction.length > 0) {
                        let shippingFields = updateDetailsForm.find('.bp-shippingField');
                        shippingAction.on('change', function (event) {
                            let $this = $(this),
                                isChecked = $this.prop('checked');

                            if (isChecked) {
                                shippingWrapper.addClass('hidden');
                                shippingFields.each(function (index, field) {
                                    $(field).prop("disabled", true);
                                });
                            } else {
                                shippingWrapper.removeClass('hidden');
                                shippingFields.each(function (index, field) {
                                    $(field).prop("disabled", false);
                                });
                            }
                        });

                        if (bidspiritUser.shipping !== undefined && bidspiritUser.shipping.countryCode !== "") {
                            shippingAction.prop("checked", false);
                            shippingAction.trigger("change");
                        }
                    }
                }

                resendEmailAction();

                if (profileLink.length) {
                    profileLink.on("click", function (event) {
                        event.preventDefault();
                        profileFormAction();
                    });
                }

                if (wishListLink.length) {
                    wishListLink.on("click", function (event) {
                        event.preventDefault();

                        if ($(wishListSection).is(":empty")) {
                            profileQuery("account/getFavorites", wishListSection);
                        }
                    });
                }

                if (bidsListLink.length) {
                    bidsListLink.on("click", function (event) {
                        event.preventDefault();

                        if ($(bidsListSection).is(":empty")) {
                            profileQuery("account/getAbsenteeBids", bidsListSection);
                        }
                    });
                }

                if (paymentMethodsLink.length) {
                    paymentMethodsLink.on("click", function (event) {
                        event.preventDefault();

                        if ($(paymentMethodsSection).is(":empty")) {
                            paymentMethodAction("users/paymentMethods/getStripeSetupSecret", paymentMethodsSection, bidspiritUser);
                        }
                    });
                }

                if (winningsListLink.length) {
                    winningsListLink.on("click", function (event) {
                        event.preventDefault();

                        if ($(winningsListSection).is(":empty")) {
                            profileQuery("account/getPurchases", winningsListSection);
                        }
                    });
                }

                if (billsListLink.length) {
                    billsListLink.on("click", function (event) {
                        event.preventDefault();

                        if ($(billsListSection).is(":empty")) {
                            billsAction(billsListSection);
                        }
                    });
                }

                function billsAction(container) {
                    // Clear the cached unpaid bills so the banner re-checks on next page load
                    clearUnpaidBillsCache();
                    $(container).html('<div class="bp-loading-bills bp-text-center"><p>'+ (window.bs_lang.loading || 'Loading...') +'</p></div>');
                    var unpaidReq = $.Deferred();
                    bidspiritQuery("bills/getUnpaidBills", {
                        sessionId: bidspiritSessionId,
                        language: LANG
                    }, function (data) {
                        var bills = data && data.response ? data.response : [];
                        if (!Array.isArray(bills)) bills = [];
                        unpaidReq.resolve(bills);
                    }, function () {
                        unpaidReq.resolve([]);
                    });

                    var paidReq = $.Deferred();
                    bidspiritQuery("bills/getPaidBills", {
                        sessionId: bidspiritSessionId,
                        language: LANG
                    }, function (data) {
                        var bills = data && data.response ? data.response : [];
                        if (!Array.isArray(bills)) bills = [];
                        paidReq.resolve(bills);
                    }, function () {
                        paidReq.resolve([]);
                    });

                    $.when(unpaidReq, paidReq).done(function(unpaidBills, paidBills) {
                        unpaidBills = unpaidBills || [];
                        paidBills = paidBills || [];
                        var allBills = unpaidBills.concat(paidBills);
                        
                        // Extract codes and dates for mapping
                        allBills.forEach(function(b) {
                            if (b.description) {
                                // Only match "for auction [code]" to avoid false positives like "Auction House"
                                var m = b.description.match(/for auction\s+#?([a-zA-Z0-9-]+)/i);
                                if (m) {
                                    b.auctionCode = m[1];
                                }
                                // Extract date from end of description (e.g., "Mar 29, 2026")
                                var mDate = b.description.match(/,\s*([A-Z][a-z]{2}\s+\d{1,2},\s*\d{4})\s*$/i);
                                if (mDate) b.auctionDateStr = mDate[1].trim();
                            }
                            // Also try billTime epoch for date
                            if (!b.auctionDateStr && b.billTime) {
                                var d = new Date(b.billTime);
                                var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
                                b.auctionDateStr = months[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear();
                            }
                            b.isPaid = (b.status && b.status.toUpperCase() === "PAID") || b.isPaid === true;
                        });

                        // Build lookups for ALL bills — pass code if available, otherwise pass date for server-side auction matching
                        var lookups = {};
                        var hasLookups = false;
                        allBills.forEach(function(b, idx) {
                            var entry = {};
                            if (b.auctionCode) {
                                entry.code = b.auctionCode;
                            }
                            if (b.auctionDateStr) {
                                entry.date = b.auctionDateStr;
                            }
                            if (entry.code || entry.date) {
                                lookups["bill_" + idx] = entry;
                                hasLookups = true;
                            }
                        });

                        if (hasLookups) {
                            $.ajax({
                                type: "post",
                                url: window.wp_data.ajax_url,
                                data: {
                                    action: "af_resolve_bill_titles",
                                    security: window.wp_nonce,
                                    lookups: lookups
                                }
                            }).done(function(res) {
                                var mapping = res.success ? res.data : {};
                                allBills.forEach(function(b, idx) {
                                    var resolvedName = mapping["bill_" + idx];
                                    if (b.description) {
                                        if (resolvedName) {
                                            var datePart = b.auctionDateStr ? " - " + b.auctionDateStr : "";
                                            b.description = "Auction: " + resolvedName + datePart;
                                        } else {
                                            // Fallback cleaning
                                            b.description = b.description.replace(/^Bill for auction\s+#?[a-zA-Z0-9-]+\s+/i, "Auction: ");
                                            b.description = b.description.replace(/\sthat took place on\s+/i, " - ");
                                            b.description = b.description.replace(/\s+-\s+[a-zA-Z0-9-]+\s+-\s+/i, " - ");
                                            b.description = b.description.replace(/\s*-\s*-\s*/, " - ");
                                        }
                                        b.invoiceNumber = b.description;
                                    }
                                });
                                renderInvoices();
                            }).fail(function() {
                                renderInvoices();
                            });
                        } else {
                            renderInvoices();
                        }

                        function renderInvoices() {
                            loadTemplate(container, "account-bills-template", {
                                items: allBills,
                                currency: currencySymbol,
                                isPaidTab: false,
                                formattedPrice: formattedPrice,
                                bidspiritServer: BIDSPIRIT_SERVER,
                                ajaxUrl: window.wp_data.ajax_url,
                                nonce: window.wp_nonce
                            }, false);
                        }
                    });
                }

                if (bidspiritUser !== undefined && bidspiritUser.number !== undefined && window.bs_data.show_bidder_number !== undefined && window.bs_data.show_bidder_number === 'on') {
                    let h1Profile = document.querySelector('.bp_profile_page .bp-header h1');
                    if (!!h1Profile) {
                        h1Profile.innerText = window.bs_lang.bidder_number.replace(/\%s/, bidspiritUser.number);
                    }
                }

                doLogout(logoutAction);
                optOut();
            }
        })();

        (function () {
            var dateTimeField = $("#dateTimeField, .bp-auction-start-date");

            if (dateTimeField.length) {
                dateTimeField.each(function (index, elem) {
                    printTime($(elem), $(elem).attr("data-time"));
                });
            }
        })();

        if (bidspiritUser !== null) {
            noticeUser(bidspiritUser);
        }

        (function () {
            let profileCustomLink = $('[href="#bp-profile"]');
            if (profileCustomLink.length) {
                let profileLink = window.bs_data.link_profile,
                    bidspiritUser = bidspiritApi.getBidspiritUser();

                profileCustomLink.each(function (index, elem) {
                    $(elem).off('click').on('click', function (event) {
                        event.preventDefault();
                        if (bidspiritUser) {
                            window.location.href = profileLink;
                        } else {
                            MicroModal.show('modal-login');
                        }
                    });
                });
            }
        })();
    }

    function userDestroy(bidspiritUser) {
        bidspiritUser = null;

        if ($("#modal-profile").length) {
            MicroModal.close("modal-profile");
            MicroModal.init(microModalInitConfig());
        }

        try {
            localStorage.removeItem("bidspiritSessionId");
            localStorage.removeItem("bidspiritAuthToken");
        } catch (e) {
            console.error("Local storage disabled");
        }

        window.location.reload();
    }

    function doLogout(logoutAction) {
        checkPoint("bp-login", true);
        logoutAction.on("click", function (event) {
            event.preventDefault();
            bidspiritQuery("users/logout", {
                sessionId: bidspiritSessionId
            }, function (data) {
                if (!checkError(data)) {
                    userDestroy(bidspiritUser);
                }
            });
        });
    }

    function optOut() {
        let optOutUserTrigger = $('#optOutUser');
        if (optOutUserTrigger.length) {
            optOutUserTrigger.off('click').on('click', function (event) {
                event.preventDefault();

                Swal.fire({
                    title: window.bs_lang.want_to_delete_user,
                    showCancelButton: true,
                    confirmButtonColor: "#DD3333",
                    cancelButtonColor: "#3085D6",
                    confirmButtonText: window.bs_lang.yes_delete_user,
                }).then((result) => {
                    if (result.isConfirmed) {
                        bidspiritQuery("users/optOut", {
                            sessionId: bidspiritSessionId
                        }, function (data) {
                            if (!checkError(data)) {
                                userDestroy(bidspiritUser);
                            }
                        });
                    }
                });
            });
        }
    }

    function printTime(elem, dateTime) {
        function getLocalTime(time) {
            var str = time;
            var re = /\(.+\)/gm;
            var found = str.match(re);

            if (found !== null) {
                return found[0];
            } else {
                return "";
            }
        }

        function addZero(i) {
            if (i < 10) {
                i = "0" + i;
            }

            return i;
        }

        if (bpIsset(window.timeZoneName) && bpIsset(window.timeZoneName) !== "") {
            var getAuctionDate = new Date(dateTime),
                polylangTimeUse = window.polylang_time,
                getAuctionDateDiff = timeShift(dateTime);
        } else {
            var getAuctionDate = new Date(dateTime),
                getAuctionDateDiff = getAuctionDate;
        }

        if (!(bpIsset(window.timeZoneName) && bpIsset(window.timeZoneName) !== "") && window.browser_time === "off") {
            getAuctionDateDiff = new Date(getAuctionDate.getTime());
        }

        if (window.format_display_time === "2" || polylangTimeUse === "on") {
            var getAuctionDateDay = addZero(getAuctionDateDiff.getDate()),
                getAuctionMonth = addZero(getAuctionDateDiff.getMonth() + 1),
                getAuctionFullYear = getAuctionDateDiff.getFullYear(),
                getAuctionHours = addZero(getAuctionDateDiff.getHours()),
                getAuctionMinutes = addZero(getAuctionDateDiff.getMinutes()),
                nameDaysArray = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][getAuctionDate.getDay()],
                nameMonthArray = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][getAuctionDate.getMonth()];
        }

        var customDateForm = elem.attr("data-custom-format"),
            customDateFormTime = elem.attr("data-custom-format-time"),
            unknownExactDate = Boolean(parseInt(elem.attr("data-unknown-exact-date"))),
            unknownDate = elem.attr("data-unknown-date"),
            localTime = getLocalTime(getAuctionDateDiff.toString()),
            polyLanguage = getCookie("pll_language");

        if (window.browser_time === "off") {
            localTime = window.timeZoneLabel !== "" ? "(" + window.timeZoneLabel + ")" : "";
        }

        var userLang = polyLanguage !== "" ? polyLanguage : navigator.language || navigator.userLanguage;
        var options = {
            timeZone: getTimeZoneFromUser(),
            formatMatcher: "basic",
            weekday: "long",
            year: "numeric",
            month: "long",
            day: "numeric",
            hour: "numeric",
            minute: "numeric",
            timeZoneName: "short"
        };

        if (elem.length) {
            if (unknownExactDate) {
                elem.html(unknownDate);
                return;
            }

            if (window.browser_time === "on" || customDateForm === "") {
                if (window.format_display_time === "2") {
                    elem.html(nameMonthArray + " " + getAuctionDateDay + ", " + getAuctionFullYear + ", " + getAuctionHours + ":" + getAuctionMinutes + " " + localTime);
                } else if (polylangTimeUse === "on") {
                    elem.html(getAuctionDateDiff.toLocaleTimeString(userLang, options));
                } else {
                    elem.html(getAuctionDateDiff.toLocaleTimeString(getLocaleFromUser(), options));
                }
            } else {
                elem.html(customDateFormTime);
            }
        }
    }

    function submitBid() {
        var singleLot = $("#single-lot"),
            notApproveStateNotice = window.bs_lang.not_approved_user,
            pendingStateNotice = window.bs_lang.pending_user_state;

        if (!bidspiritUser) {
            try {
                MicroModal.show("modal-login", microModalInitConfig());
            } catch (e) {
                console.error(e);
            }
        } else if (bidspiritUser.approvalState === "PENDING") {
            noticeSwall("error", window.bs_lang.oops, pendingStateNotice);
        } else if (bidspiritUser.approvalState === "INCOMPLETE_PROFILE") {
            noticeSwall("error", window.bs_lang.oops, notApproveStateNotice);
        } else {
            var data = getDataForm("bidFormSection"),
                modalBidForm = "#modal-bid-content",
                lotName = $(modalBidForm).attr("data-name"),
                houseInfo = bidspiritApi.getAuctionHouseData(),
                auctionInfo = bidspiritApi.getAuctionInfo(),
                lotLinkTerm = window.bs_data.page_terms,
                additionalNotice = false,
                additionalNoticeText = "",
                auctionItemInfo = bidspiritApi.getAuctionItemInfo(),
                fullPriceVat = auctionItemInfo.item.fullPriceVat,
                auctionCommission = auctionInfo.commission;

            data.sessionId = bidspiritSessionId;
            data.auctionId = currentAuctionNumber;
            data.lotIndex = currentItemInfo.lotIndex;
            data.bidFormUrl = window.location.href;
            data.sendBidEmails = false;
            data.sendOverBidEmails = false;

            if (parseInt(data.price) >= currentItemInfo.buyoutPrice) {
                additionalNotice = true;
                additionalNoticeText = window.bs_lang.buyout_notice.replace(/#price#/, formattedPrice(currentItemInfo.buyoutPrice, currencySymbol));
            }

            MicroModal.show("modal-bid", microModalInitConfig());
            loadTemplate(modalBidForm, "modal-bid-template", {
                index: data.lotIndex,
                name: lotName,
                currentCurrency: currencySymbol,
                price: data.price,
                fullPrice: getCommissionPrice(data.price),
                fullPriceInfo: getFullPriceInfo(currentItemInfo, auctionInfo, data.price),
                linkTerms: lotLinkTerm,
                additionalNotice: additionalNotice,
                additionalNoticeText: additionalNoticeText,
                auctionHouseData: auctionHouseData,
                fullPriceVat: fullPriceVat,
                auctionCommission: auctionCommission,
                user: bidspiritUser,
                auctionItemInfo: auctionItemInfo,
                itemInfo: currentItemInfo,
                settings: auctionSettingsData,
                additionalMessage: autoChargingCreditCardMessage(auctionSettingsData)
            }, false, function () {
                $(modalBidForm).off("click", "#agreeBid").on("click", "#agreeBid", function (event) {
                    event.preventDefault();
                    var bsOptions = window.bs_data,
                        taxNumberNotRequired = bsOptions.tax_number_required !== undefined && bsOptions.tax_number_required === "off";

                    function userGate(bidspiritUser) {
                        if (bidspiritUser.taxNumber !== undefined && bidspiritUser.taxNumber !== "") {
                            return true;
                        }

                        return false;
                    }

                    var subData = getDataForm("subBidFormSection");

                    if (subData) {
                        data.sendBidEmails = subData.sendBidEmails !== undefined && subData.sendBidEmails === "true";
                        data.sendOverBidEmails = subData.sendOverBidEmails !== undefined && subData.sendOverBidEmails === "true";
                        data.callUserWhenItemIsLive = subData.callUserWhenItemIsLive !== undefined && subData.callUserWhenItemIsLive === "true";
                        bidspiritUser.sendBidEmails = data.sendBidEmails;
                        bidspiritUser.sendOverBidEmails = data.sendOverBidEmails;
                    }

                    if (taxNumberNotRequired || userGate(bidspiritUser)) {
                        var dataAlert = {
                            sessionId: data.sessionId,
                            auctionId: data.auctionId,
                            lotIndex: data.lotIndex,
                            isOn: true
                        };
                        bidspiritQuery("items/placeBid", data, function (data) {
                            if (!checkError(data)) {
                                console.log("test1", data);
                                handleSubmitResponse(data.response);
                                bidspiritQuery("items/setItemAlert", dataAlert, function () {});
                                data.response.data = {
                                    auctionId: dataAlert.auctionId,
                                    lotIndex: dataAlert.lotIndex,
                                    user: bidspiritUser.email
                                };
                                hangUpEvent("bp:after-items-place-bid", data.response);
                                afLogIP("bid", bidspiritUser);

                                // Record bid count
                                if (typeof AuctionForgeBidCount !== "undefined") {
                                    var bidPostId = $("#af-bid-count-display").attr("data-post-id") || "";
                                    if (bidPostId) {
                                        $.post(AuctionForgeBidCount.ajaxUrl, {
                                            action: "auctionforge_record_bid",
                                            nonce: AuctionForgeBidCount.nonce,
                                            post_id: bidPostId
                                        }, function(resp) {
                                            if (resp.success && resp.data && resp.data.bid_count !== undefined) {
                                                var $el = $("#af-bid-count-display");
                                                if ($el.length) {
                                                    var svg = $el.find("svg").prop("outerHTML") || "";
                                                    var cnt = resp.data.bid_count;
                                                    $el.html(svg + cnt + " " + (cnt === 1 ? "bid" : "bids"));
                                                }
                                            }
                                        });
                                    }
                                }
                            }
                        });
                        MicroModal.close("modal-bid");
                    } else {
                        MicroModal.close("modal-bid");
                        noticeSwall("error", window.bs_lang.tax_number_required, window.bs_lang.tax_number_required_label, {}, function () {
                            var linkProfile = window.bs_data.link_profile;

                            if (linkProfile !== undefined && linkProfile !== "link") {
                                window.location = linkProfile;
                            }
                        });
                    }
                });
                $(modalBidForm).off("click", "#dontAgreeBid").on("click", "#dontAgreeBid", function (event) {
                    event.preventDefault();
                    MicroModal.close("modal-bid");
                });
            });
        }
    }

    function showTermsCondModal() {
        // Load plugin legal agreements directly (no BidSpirit terms)
        afLoadLegalAgreements(function(agreements) {
            if (agreements && agreements.length > 0) {
                afRenderLegalAgreements('#af-legal-agreements-terms', agreements);
            }
        });

        $("#requestApprovalTermsAction").off("click").on("click", function (event) {
            event.preventDefault();

            // Validate legal agreements
            if (!afValidateLegalAgreements('#af-legal-agreements-terms')) {
                noticeSwall("info", "", "Please read and accept all required agreements before requesting approval");
                return;
            }

            let $this = $(this),
                auctionInfo = bidspiritApi.getAuctionInfo(),
                data = {};
            data.sessionId = bidspiritSessionId;
            data.auctionId = auctionInfo.id;
            $this.prop("disabled", true);
            bidspiritPostQuery("approvals/requestToParticipateInAuction", data, function (data) {
                if (!checkError(data)) {
                    // Log legal agreement acceptance
                    var userEmail = (bidspiritUser && bidspiritUser.email) ? bidspiritUser.email : '';
                    afLogLegalAgreements('#af-legal-agreements-terms', auctionInfo.id, userEmail);

                    MicroModal.close("modal-request-approval-terms");
                    approvalInfo(auctionInfo.id);
                }
            }, function () {
            }, function () {
                $this.prop("disabled", false);
            });
        });
        MicroModal.show("modal-request-approval-terms", microModalInitConfig());
    }

    function bidProcessAction(modalBidForm, params, data, dataAlert) {
        MicroModal.show("modal-bid", microModalInitConfig());
        loadTemplate(modalBidForm, "modal-bid-template", params, false, function () {
            $(modalBidForm).off("click", "#agreeBid").on("click", "#agreeBid", function (event) {
                event.preventDefault();
                var subData = getDataForm("subBidFormSection");

                if (subData) {
                    data.sendBidEmails = subData.sendBidEmails !== undefined && subData.sendBidEmails === "true";
                    data.sendOverBidEmails = subData.sendOverBidEmails !== undefined && subData.sendOverBidEmails === "true";
                    data.callUserWhenItemIsLive = subData.callUserWhenItemIsLive !== undefined && subData.callUserWhenItemIsLive === "true";
                    bidspiritUser.sendBidEmails = data.sendBidEmails;
                    bidspiritUser.sendOverBidEmails = data.sendOverBidEmails;
                }

                bidspiritQuery("items/placeBid", data, function (data) {
                    if (!checkError(data)) {
                        var response = data.response;

                        let type = "info";
                        if (response.leadingBidCode === "ANOTHER_BID_HIGHER" || response.leadingBidCode === "ANOTHER_BID_EARLIER") {
                            type = "error";
                        }
                        noticeSwall(type, getLeadingBidMessage(response.leadingBidCode));

                        bidspiritQuery("items/setItemAlert", dataAlert, function () {
                        });
                        updateDisplay();
                        data.response.data = {
                            auctionId: dataAlert.auctionId,
                            lotIndex: dataAlert.lotIndex,
                            user: bidspiritUser.email
                        };
                        hangUpEvent("bp:after-items-place-bid", data.response);
                        afLogIP("bid", bidspiritUser);

                                // Record bid count
                                if (typeof AuctionForgeBidCount !== "undefined") {
                                    var bidPostId = $("#af-bid-count-display").attr("data-post-id") || "";
                                    if (bidPostId) {
                                        $.post(AuctionForgeBidCount.ajaxUrl, {
                                            action: "auctionforge_record_bid",
                                            nonce: AuctionForgeBidCount.nonce,
                                            post_id: bidPostId
                                        }, function(resp) {
                                            if (resp.success && resp.data && resp.data.bid_count !== undefined) {
                                                var $el = $("#af-bid-count-display");
                                                if ($el.length) {
                                                    var svg = $el.find("svg").prop("outerHTML") || "";
                                                    var cnt = resp.data.bid_count;
                                                    $el.html(svg + cnt + " " + (cnt === 1 ? "bid" : "bids"));
                                                }
                                            }
                                        });
                                    }
                                }
                    }

                    MicroModal.close("modal-bid");
                });
            });
            $(modalBidForm).off("click", "#dontAgreeBid").on("click", "#dontAgreeBid", function (event) {
                event.preventDefault();
                MicroModal.close("modal-bid");
            });
        });
    }

    function submitBidCatalog(lot, minBidPrice, itemInfoData) {
        var singleLot = lot,
            notApproveStateNotice = window.bs_lang.not_approved_user,
            pendingStateNotice = window.bs_lang.pending_user_state;
        currentItemInfo = itemInfoData.response.itemsInfo[singleLot.attr("data-lot-index")];
        currentItemInfo.buyoutPrice = minBidPrice;
        MicroModal.init(microModalInitConfig());

        if (!bidspiritUser) {
            try {
                MicroModal.show("modal-login", microModalInitConfig());
            } catch (e) {
                console.error(e);
            }
        } else if (bidspiritUser.approvalState === "PENDING") {
            noticeSwall("error", window.bs_lang.oops, pendingStateNotice);
        } else if (bidspiritUser.approvalState === "INCOMPLETE_PROFILE") {
            noticeSwall("error", window.bs_lang.oops, notApproveStateNotice);
        } else {
            var data = getDataForm("bidFormSection"),
                modalBidForm = "#modal-bid-content",
                lotName = lot.find(".bp-lot__title a").text().replace(/Lot\s\d+\:/, ""),
                lotLinkTerm = window.bs_data.page_terms,
                additionalNotice = false,
                additionalNoticeText = "",
                auctionInfo = bidspiritApi.getAuctionInfo(),
                fullPriceVat = Boolean(parseInt(lot.attr("data-full-price-vat"))),
                auctionCommission = auctionInfo.commission;
            data.sessionId = bidspiritSessionId;
            data.auctionId = currentAuctionNumber;
            data.lotIndex = currentItemInfo.lotIndex;
            data.bidFormUrl = lot.find("a").attr("href");
            data.sendBidEmails = false;
            data.sendOverBidEmails = false;

            if (parseInt(data.price) >= currentItemInfo.buyoutPrice) {
                additionalNotice = true;
                additionalNoticeText = window.bs_lang.buyout_notice.replace(/#price#/, formattedPrice(currentItemInfo.buyoutPrice, currencySymbol));
            }

            if (data.price === undefined) {
                data.price = minBidPrice;
            }

            var params = {
                index: data.lotIndex,
                name: lotName,
                currentCurrency: currencySymbol,
                price: data.price,
                fullPrice: getCommissionPrice(data.price, fullPriceVat, auctionCommission),
                fullPriceInfo: getFullPriceInfo(currentItemInfo, auctionInfo, data.price),
                linkTerms: lotLinkTerm,
                additionalNotice: additionalNotice,
                additionalNoticeText: additionalNoticeText,
                auctionHouseData: auctionHouseData,
                fullPriceVat: fullPriceVat,
                auctionCommission: auctionCommission,
                user: bidspiritUser,
                itemInfo: currentItemInfo,
                settings: auctionSettingsData,
                additionalMessage: autoChargingCreditCardMessage(auctionSettingsData)
            };

            function userGate(bidspiritUser) {
                if (bidspiritUser.taxNumber !== undefined && bidspiritUser.taxNumber !== "") {
                    return true;
                }

                return false;
            }

            var bsOptions = window.bs_data,
                taxNumberNotRequired = bsOptions.tax_number_required !== undefined && bsOptions.tax_number_required === "off";

            if (taxNumberNotRequired || userGate(bidspiritUser)) {
                var auctionApprovalState = bidspiritApi.getAuctionApprovalState();
                var dataAlert = {
                    sessionId: data.sessionId,
                    auctionId: data.auctionId,
                    lotIndex: data.lotIndex,
                    isOn: true
                };

                if (auctionInfo.approvalRequired !== undefined && auctionInfo.approvalRequired) {
                    if (auctionInfo.paymentMethodRequired !== undefined && auctionInfo.paymentMethodRequired === true) {
                        if (bidspiritApi.getAuctionApprovalState() === "APPROVED") {
                            bidProcessAction(modalBidForm, params, data, dataAlert);
                        } else if (bidspiritApi.getAuctionApprovalState() === "NOT_REQUESTED") {
                            if (paymentMethods.length > 0) {
                                modalRequestApprovalShow();
                                MicroModal.init(microModalInitConfig());
                            } else {
                                addPaymentMethodCallback();
                            }
                        } else if (bidspiritApi.getAuctionApprovalState() === "APPROVAL_REQUESTED") {
                            noticeSwall("info", "", window.bs_lang.approval_info_approval_requested);
                        } else {
                            if (bidspiritApi.getAuctionApprovalState() === "PENDING") {
                                noticeSwall("error", window.bs_lang.oops, window.bs_lang.pending_user_state);
                            } else if (bidspiritApi.getAuctionApprovalState() === "INCOMPLETE_PROFILE") {
                                noticeSwall("error", window.bs_lang.oops, window.bs_lang.not_approved_user);
                            }
                        }
                    } else if (auctionInfo.paymentMethodRequired !== undefined && auctionInfo.paymentMethodRequired === false) {
                        if (bidspiritApi.getAuctionApprovalState() === "APPROVED") {
                            bidProcessAction(modalBidForm, params, data, dataAlert);
                        } else if (bidspiritApi.getAuctionApprovalState() === "NOT_REQUESTED") {
                            showTermsCondModal();
                        } else if (bidspiritApi.getAuctionApprovalState() === "APPROVAL_REQUESTED") {
                            noticeSwall("info", "", window.bs_lang.approval_info_approval_requested);
                        } else {
                            if (bidspiritApi.getAuctionApprovalState() === "PENDING") {
                                noticeSwall("error", window.bs_lang.oops, window.bs_lang.pending_user_state);
                            } else if (bidspiritApi.getAuctionApprovalState() === "INCOMPLETE_PROFILE") {
                                noticeSwall("error", window.bs_lang.oops, window.bs_lang.not_approved_user);
                            }
                        }
                    } else {
                        bidProcessAction(modalBidForm, params, data, dataAlert);
                    }

                    MicroModal.init(microModalInitConfig());
                } else {
                    bidProcessAction(modalBidForm, params, data, dataAlert);
                }
            } else {
                MicroModal.close("modal-bid");
                noticeSwall("error", window.bs_lang.tax_number_required, window.bs_lang.tax_number_required_label, {}, function () {
                    var linkProfile = window.bs_data.link_profile;

                    if (linkProfile !== undefined && linkProfile !== "link") {
                        window.location = linkProfile;
                    }
                });
            }
        }
    }

    function getApprovalStateInfo(user) {
        var userState = $("#profile-account-section");

        if (!user.emailConfirmed) {
            return userState.attr("data-confirm-email");
        }

        switch (user.approvalState) {
            case "INCOMPLETE_PROFILE":
                return userState.attr("data-incomplete-profile");

            case "PENDING":
                return userState.attr("data-pending");
        }

        return "";
    }

    function submitUpdateDetails() {
        function filterData(data) {
            let updatedData = {
                data: {},
                errors: {}
            };

            if (data.countryCode !== undefined && data.countryCode === "US") {
                data.stateCode = data.state;
                data.state = "";
                data.province = "";
            } else {
                data.stateCode = "";
            }

            for (const [key, value] of Object.entries(data)) {
                if (key === "") {
                    continue;
                }

                if (key === "firstName" || key === "lastName") {
                    if (value.match(/\@/)) {
                        updatedData["errors"][key] = window.bs_lang.profile_field_error.replace(/\%s/, key);
                    }
                }

                updatedData["data"][key] = value;
            }

            return updatedData;
        }

        var data = getDataForm("updateDetailsSection"),
            formParent = $("#updateDetailsSection"),
            shippingAction = $("#profileShippingCheckbox"),
            approvalState = bidspiritUser.approvalState,
            postConfirmationLink = formParent.attr("action");
        data.sessionId = bidspiritSessionId;
        data.postConfirmationLink = postConfirmationLink;
        let tmpData = filterData(data);
        data = tmpData["data"];

        if (Object.keys(tmpData["errors"]).length > 0) {
            let keys = Object.keys(tmpData["errors"]),
                message = window.bs_lang.profile_error;

            if (keys[0] !== undefined) {
                message = tmpData["errors"][keys[0]];
            }

            noticeSwall("error", "Error", message);
        } else {
            if (approvalState === "PENDING") {
                var info = bidspiritApi.getAuctionHouseData(),
                    title = window.bs_lang.you_are_still_pending_approval.replace(/\%1s/, info.name),
                    message = window.bs_lang.you_are_still_pending_approval_body.replace(/\%1s/, info.phone).replace(/\%2s/, info.email);
                noticeSwall("info", title, message);
            } else {
                bidspiritPostQuery("users/updateDetails", data, function (response) {
                    if (response.response.success === false) {
                        noticeSwall("error", "Error", data.response.errorMessage);
                    } else {
                        let userData = response.response,
                            shippingData = {};
                        Promise.all([
                            new Promise(function (resolve) {
                                if (shippingAction[0] !== undefined && !shippingAction.prop('checked')) {
                                    let shippingFields = Object.keys(data)
                                        .filter((key) => key.includes("shipping"))
                                        .reduce((object, key) => {
                                            return Object.assign(object, {
                                                [key.replace(/shipping\./, "")]: data[key]
                                            });
                                        }, {});

                                    bidspiritPostQuery("users/updateShippingAddress",
                                        Object.assign({sessionId: bidspiritSessionId}, shippingFields),
                                        function (response) {
                                            if (response.response.success === false) {
                                                shippingData = response.response;
                                                noticeSwall("error", "Error", response.response.errorMessage);
                                            } else {
                                                userData.shipping = response.response;
                                                resolve();
                                            }
                                        });
                                } else {
                                    let user = bidspiritApi.getBidspiritUser();
                                    if (user.shipping !== undefined) {
                                        bidspiritPostQuery("users/updateShippingAddress",
                                            Object.assign({sessionId: bidspiritSessionId}, {
                                                countryCode: "",
                                                stateCode: "",
                                                state: "",
                                                city: "",
                                                address: "",
                                                zipCode: ""
                                            }),
                                            function () {
                                                shippingData = response.response;
                                                userData.shipping = undefined;
                                                resolve();
                                            });
                                    } else {
                                        resolve();
                                    }
                                }
                            }),
                        ]).then(function (response) {
                            bidspiritApi.setBidspiritUser(userData);
                            updateDisplay();
                            noticeSwall("info", window.bs_lang.profile_changes_saved, window.bs_lang.profile_changes_saved_body, {}, function () {
                                if (approvalState !== bidspiritUser.approvalState) {
                                    window.location = postConfirmationLink;
                                }
                            });
                        });
                    }
                });

            }
        }
    }

    function handleSubmitResponse(data) {
        currentItemInfo.selfAbsenteeBid = data.selfAbsenteeBid;
        currentItemInfo.leadingBid = data.leadingBid;
        displayBidFormData(currentItemInfo);

        let type = "info";
        if (data.leadingBidCode === "ANOTHER_BID_HIGHER" || data.leadingBidCode === "ANOTHER_BID_EARLIER") {
            type = "error";
        }
        noticeSwall(type, getLeadingBidMessage(data.leadingBidCode));
    }

    function disableLoader() {
        $("#bsLoader").addClass(window.bs_data.hidden_class);
    }

    function toggleFavorite(lot, elem, auctionNumber, delLot) {
        var lotIndex = lot.attr("data-lot-index"),
            wishListClass = "bp__wishlist-active",
            isFavorite = !$(elem).hasClass(wishListClass);

        if (!bidspiritUser) {
            try {
                MicroModal.show("modal-login", microModalInitConfig());
            } catch (e) {
                console.error(e);
            }
        } else {
            bidspiritQuery("items/setFavorite", {
                sessionId: bidspiritSessionId,
                auctionId: auctionNumber,
                lotIndex: lotIndex,
                isFavorite: isFavorite
            }, function (data) {
                if (!checkError(data)) {
                    if (data.response.success) {
                        if (isFavorite) {
                            $(elem).addClass(wishListClass);
                        } else {
                            $(elem).removeClass(wishListClass);

                            if (delLot) {
                                lot.remove();
                            }
                        }
                    }
                }
            });
        }
    }

    function getLeadingBidMessage(leadingBidCode) {
        var response = "";

        switch (leadingBidCode) {
            case "YOU_ARE_THE_HIGH_BIDDER":
                response = window.bs_lang.success_high_bidder;
                break;

            case "ANOTHER_BID_HIGHER":
                response = window.bs_lang.higher_your_bid_has_been_outbid;
                break;

            case "ANOTHER_BID_EARLIER":
                response = window.bs_lang.earlier_your_bid_has_been_outbid;
                break;

            case "SYNC_ERROR":
                response = window.bs_lang.sync_error;
                break;
        }

        return response;
    }

    function tabs() {
        $(".tools-wrapper").on("click", ".bp-tabs-link a", function (event) {
            event.preventDefault();
            var $this = $(this),
                parent = $this.parents(".bp-tabs-block"),
                idTab = parent.attr("data-tab-id"),
                href = $this.attr("href");
            window.location.href = window.location.origin + window.location.pathname + href;

            if ($(href).length) {
                parent.find(".nav-link").removeClass("active");
                $("#" + idTab + " > *").removeClass("active");
                $this.addClass("active");
                $(href).addClass("active");
            }
        });
    }

    function activeTabs() {
        var activeTab = $('.bp-tabs-block a[href="' + window.location.hash + '"]');

        if (activeTab.length) {
            activeTab.trigger("click");
        }
    }

    /**
     * Global hashchange listener — allows menu links, external links, and
     * in-page links to switch profile tabs even when already on the page.
     * e.g. a header menu link to /profile/#bp-bills will work from any tab.
     */
    $(window).on("hashchange", function() {
        var hash = window.location.hash;
        if (!hash) return;

        var tab = $('.bp-tabs-block a[href="' + hash + '"]');
        if (tab.length) {
            tab.trigger("click");

            // Also open the spoiler/accordion on mobile if it's collapsed
            var spoilerTrigger = $(hash + " .bp-spoiler-trigger");
            if (spoilerTrigger.length && !spoilerTrigger.hasClass("active")) {
                spoilerTrigger.trigger("click");
            }

            // Smooth scroll to the tab section
            var section = $(hash);
            if (section.length) {
                $("html, body").animate({ scrollTop: section.offset().top - 100 }, 300);
            }
        }
    });

    function spoiler() {
        $(document).on("click", ".bp-spoiler-trigger", function (e) {
            e.preventDefault();
            $(this).toggleClass("active");
            $(this).parent().toggleClass("active-spoiler").find(".bp-spoiler-block").first().toggleClass("active");
        });
    }

    function loginLink() {
        function loadLoginLink(login) {
            loadTemplate(".wrpLoginLink", "account-link-profile", {
                login: login
            }, false, function () {
                MicroModal.init(microModalInitConfig());
            });

            if ($(".wrpRegisterLink").length) {
                loadTemplate(".wrpRegisterLink", "account-link-register", {
                    login: login
                }, false, function () {
                    MicroModal.init(microModalInitConfig());
                });
            }
        }

        var loginLink = $(".bp-login-link"),
            menu = loginLink.parents(".menu");

        if (loginLink.length && bidspiritUser) {
            loadLoginLink(true);

            if (menu !== undefined) {
                menu.addClass("user-is-authorize");
                menu.removeClass("user-is-not-authorize");
            }
        } else if (!bidspiritUser) {
            loadLoginLink(false);

            if (menu !== undefined) {
                menu.removeClass("user-is-authorize");
                menu.addClass("user-is-not-authorize");
            }
        }
    }

    function resendEmailAction() {
        var resendEmailSection = $("#resendEmailSection");

        if (resendEmailSection.length) {
            resendEmailSection.on("click", function (event) {
                event.preventDefault();
                bidspiritQuery("users/resendConfirmationMail", {
                    sessionId: bidspiritSessionId,
                    postConfirmationLink: window.location.href
                }, function (data) {
                    if (!bPcheckError(data)) {
                        if (data.response.success) {
                            noticeSwall("success", "Email confirmation sent");
                        } else {
                            noticeSwall("error", "Unknown error");
                        }
                    }
                });
            });
        }
    }

    function saveFirebaseUser() {
        try {
            var firebaseTokenFCM = localStorage.getItem("token_firebase_push_id");
        } catch (e) {
            firebaseTokenFCM = null;
        }

        if (firebaseTokenFCM !== null) {
            if (bidspiritUser.leadingBidAlertsEnabled !== undefined && bidspiritUser.leadingBidAlertsEnabled !== true) {
                bidspiritQuery("users/setLeadingBidAlertsEnabled", {
                    sessionId: bidspiritSessionId,
                    isEnabled: true
                }, function (data) {
                    if (!checkError(data)) {
                    }
                });
            }

            restQuery("user/login", "POST", {
                bidspirit_user_email: bidspiritUser.email,
                firebase_id: firebaseTokenFCM
            }, function (response) {
                console.info(response);
            });
        }
    }

    function widgetSliders() {
        new SwiperBP(".widget-lots", {
            speed: 400,
            slidesPerView: 1,
            spaceBetween: 10,
            centeredSlides: true,
            freeMode: false,
            autoplay: {
                delay: 4000
            },
            breakpoints: {
                977: {
                    slidesPerView: 3,
                    spaceBetween: 15
                },
                1200: {
                    slidesPerView: 5,
                    spaceBetween: 30,
                    centeredSlides: false
                }
            }
        });
    }

    function updateLotsWidget() {
        if ($(".bt-wi-lots_wrp").length) {
            var widgets = $(".bt-wi-lots");
            widgets.each(function (index, widget) {
                var lots = $(widget).find(".bp-lot"),
                    hash = $(widget).attr("data-hash"),
                    auctions = {};

                if (hash === undefined) {
                    hash = "";
                }

                lots.each(function (index, elem) {
                    var $this = $(elem),
                        auctionId = $this.attr("data-auction-id"),
                        lotId = $this.attr("data-lot-index");

                    if (auctions[auctionId] === undefined && auctionId !== "") {
                        auctions[auctionId] = [];
                    }

                    if (lotId !== "") {
                        auctions[auctionId].push(lotId);
                    }
                });
                $.each(auctions, function (index, items) {
                    if (items.length > 0 && index !== "undefined") {
                        bidspiritQuery("items/getItemsInfo", {
                            sessionId: bidspiritSessionId,
                            auctionId: index,
                            lotIndexes: items.join(",")
                        }, function (data) {
                            if (!checkError(data)) {
                                var bidsInfoData = data.response;

                                if (bidsInfoData.itemsInfo !== undefined && items.length > 0) {
                                    for (var i = 0; i < items.length; i++) {
                                        var itemIndex = items[i],
                                            itemRow = $("#single-lot-" + index + "-" + itemIndex + hash);

                                        if (bidsInfoData.itemsInfo[itemIndex] !== undefined) {
                                            var itemInfo = bidsInfoData.itemsInfo[itemIndex];
                                        } else {
                                            console.log(itemIndex);
                                            continue;
                                        }

                                        var content = "";

                                        try {
                                            var dataContent = itemRow.attr("data-content");

                                            if (dataContent !== undefined) {
                                                content = JSON.parse(urldecode(itemRow.attr("data-content")));
                                            }
                                        } catch (e) {
                                            console.error("error parse content of lot");
                                        }

                                        loadTemplate("#single-lot-" + index + "-" + itemIndex + hash + "-content", "lot-content-template", {
                                            auctionInfo: bidsInfoData,
                                            auctionData: bidspiritApi.getAuctionInfo() || {},
                                            itemInfo: itemInfo,
                                            title: itemRow.find(".bp-lot__title").html(),
                                            link: itemRow.find(".img-block").attr("href"),
                                            content: content,
                                            currency: currencySymbol,
                                            hiddenPrice: false,
                                            postAuctionSaleOpenedUntil: 0,
                                            postAuctionSaleOpened: false,
                                            showEstimatedPriceInItemsList: (itemInfo.estimatedPrice !== undefined),
                                            displayStartPriceInCatalog: (itemInfo.startPrice !== undefined),
                                            bidspiritUser: bidspiritUser,
                                            bidsInCatalog: false,
                                            isShop: Boolean(parseInt($("#catalog-section").attr("data-is-shop"))),
                                            houseInfo: bidspiritApi.getAuctionHouseData() || {},
                                            settings: bidspiritApi.getAuctionSettingsData() || {},//#B141 task
                                            estimatedPrice: itemRow.attr("data-estimated-price"),
                                            // nextMinBid: nextMinBid,
                                        }, true, function () {
                                            if (itemInfo !== undefined) {
                                                hangUpEvent("bp:after-getItemsInfo-content-item", itemInfo, itemRow);
                                            }
                                        });
                                    }

                                    hangUpEvent("bp:after-getItemsInfo-item", bidsInfoData);
                                }
                            }
                        });
                    }
                });
            });
        }
    }

    function onPageAction() {
        function auctionAlertAction() {
            $("body").on("click", ".auction-follow-action", function (event) {
                event.preventDefault();
                var $this = $(event.target),
                    auctionId = $this.attr("data-auction-id");
                bidspiritQuery("auctions/setAuctionAlert", {
                    sessionId: bidspiritSessionId,
                    auctionId: auctionId,
                    isOn: true
                }, function (data) {
                    if (data.response.success) {
                        noticeSwall("success", "Success", "");
                    } else {
                        noticeSwall("error", window.bs_lang.oops);
                    }
                });
            });
        }

        auctionAlertAction();
    }

    function singleLotAction() {
        if (!!document.querySelector('#catalog-section')) {
            let catalogHref = window.location.href.replace(/\#.+/, '');
            localStorage.setItem('catalog', catalogHref);
            console.log("update catalog:", catalogHref);
        }

        if (!!document.querySelector('.goback')) {
            $(".goback").each(function (index, elem) {
                $(elem).on("click", function (event) {
                    event.preventDefault();
                    let catalog = localStorage.getItem('catalog'),
                        lotId = $(this).attr('data-id'),
                        elemHref = $(this).attr('href');

                    if (catalog) {
                        catalog = catalog.replace(/#$/, '');
                    }

                    // If localStorage catalog doesn't match this lot's auction, use the href instead
                    if (!catalog || (elemHref && catalog.replace(/\/$/, '') !== elemHref.replace(/\/$/, '').replace(/#.*$/, ''))) {
                        window.location = elemHref + (lotId || '');
                    } else {
                        window.location = catalog + lotId;
                    }
                });
            });
        }
    }

    document.addEventListener("DOMContentLoaded", function (event) {
        try {
            if (!bpIsset(window.localStorage)) {
                noticeSwall("error", window.bs_lang.storage_not_working);
            }
        } catch (e) {
            noticeSwall("error", window.bs_lang.storage_not_working);
        }

        initApp();
        init();
        var loginForm = $(".bp-login-api"),
            bidForm = $("#bidFormSection"),
            loginModal = $("#modal-login"),
            registerModal = $("#modal-register"),
            registerForm = $(".bp-register-api"),
            logoutAction = $("#doLogout"),
            forgottenAction = $(".doForgotten"),
            wishListButtons = $(".bp-lot .bp__wishlist"),
            errorBlockSelector = ".errors-group";

        if (loginForm.length) {
            loginForm.on("submit", function (event) {
                event.preventDefault();
                submitLogin(event);
            });
        }

        if (forgottenAction.length) {
            forgottenAction.each(function (index, elem) {
                var $this = $(elem),
                    formParent = $(".bp-login-api");
                $this.on("click", function (event) {
                    event.preventDefault();
                    bidspiritPostQuery("users/sendPasswordReset", {
                        sessionId: bidspiritSessionId,
                        email: formParent.find("[name='email']").val(),
                        language: LANG,
                        postResetPage: window.location.href
                    }, function (data) {
                        if (!checkError(data)) {
                            if (data.response.success) {
                                noticeSwall("info", window.bs_lang.profile_password_reset);
                            } else {
                                noticeSwall("error", window.bs_lang.profile_email_not_found);
                            }
                        }
                    });
                });
            });
        }

        if (registerForm.length) {
            registerForm.each(function (index, elem) {
                $(elem).on("submit", function (event) {
                    var $this = $(event.target),
                        acceptPrivacy = $this.attr("data-accept-privacy");
                    event.preventDefault();
                    var errorBlock = $this.find(errorBlockSelector),
                        checkboxPersonalData = $(event.target).find('[name="personal-data"]');

                    if (errorBlock === undefined) {
                        errorBlock = registerModal.find(errorBlockSelector);
                    }

                    errorBlock.empty();

                    if (acceptPrivacy === "on") {
                        if (checkboxPersonalData.length && checkboxPersonalData.is(":checked")) {
                            submitRegister(event);
                        } else {
                            var error = window.bs_lang["notice_personal_data"];
                            errorBlock.empty().append("<p>" + error + "</p>").removeClass(window.bs_data.hidden_class);
                        }
                    } else {
                        submitRegister(event);
                    }
                });
            });
        }

        if (bidForm.length) {
            bidForm.unbind("submit");
            bidForm.on("submit", function (event) {
                event.preventDefault();

                if (!bidspiritUser) {
                    try {
                        MicroModal.show("modal-login", microModalInitConfig());
                    } catch (e) {
                        console.error(e);
                    }

                    return;
                }

                var auctionInfo = bidspiritApi.getAuctionInfo();

                if (auctionInfo.state !== "ENDED") {
                    if (auctionInfo.approvalRequired !== undefined && auctionInfo.approvalRequired) {
                        if (auctionInfo.paymentMethodRequired !== undefined && auctionInfo.paymentMethodRequired === true) {
                            if (bidspiritApi.getAuctionApprovalState() === "APPROVED") {
                                submitBid();
                            } else if (bidspiritApi.getAuctionApprovalState() === "NOT_REQUESTED") {
                                if (paymentMethods.length > 0) {
                                    modalRequestApprovalShow();
                                    MicroModal.init(microModalInitConfig());
                                } else {
                                    addPaymentMethodCallback();
                                }
                            } else if (bidspiritApi.getAuctionApprovalState() === "APPROVAL_REQUESTED") {
                                noticeSwall("info", "", window.bs_lang.approval_info_approval_requested);
                            } else {
                                if (bidspiritApi.getAuctionApprovalState() === "PENDING") {
                                    noticeSwall("error", window.bs_lang.oops, window.bs_lang.pending_user_state);
                                } else if (bidspiritApi.getAuctionApprovalState() === "INCOMPLETE_PROFILE") {
                                    noticeSwall("error", window.bs_lang.oops, window.bs_lang.not_approved_user);
                                }
                            }
                        } else if (auctionInfo.paymentMethodRequired !== undefined && auctionInfo.paymentMethodRequired === false) {
                            if (bidspiritApi.getAuctionApprovalState() === "APPROVED") {
                                submitBid();
                            } else if (bidspiritApi.getAuctionApprovalState() === "NOT_REQUESTED") {
                                showTermsCondModal();
                            } else if (bidspiritApi.getAuctionApprovalState() === "APPROVAL_REQUESTED") {
                                noticeSwall("info", "", window.bs_lang.approval_info_approval_requested);
                            } else {
                                if (bidspiritApi.getAuctionApprovalState() === "PENDING") {
                                    noticeSwall("error", window.bs_lang.oops, window.bs_lang.pending_user_state);
                                } else if (bidspiritApi.getAuctionApprovalState() === "INCOMPLETE_PROFILE") {
                                    noticeSwall("error", window.bs_lang.oops, window.bs_lang.not_approved_user);
                                }
                            }
                        } else {
                            submitBid();
                        }

                        MicroModal.init(microModalInitConfig());
                    } else {
                        submitBid();
                    }
                }
            });
        }

        if (logoutAction.length) {
            doLogout(logoutAction);
        }

        if (loginModal.length) {
            loginModal.on("click", "#doRegister", function (event) {
                event.preventDefault();
                MicroModal.close("modal-login");
                MicroModal.init(microModalInitConfig());
                MicroModal.show("modal-register");
            });
        }

        if (registerModal.length) {
            registerModal.on("click", "#doLogin", function (event) {
                event.preventDefault();
                MicroModal.close("modal-register");
                MicroModal.init(microModalInitConfig());
                MicroModal.show("modal-login", microModalInitConfig());
            });
        }

        $("#single-lot, #catalog-section").on("click", wishListButtons, function (event) {
            var elem = event.target,
                lot = $(elem).parents(".bp-lot");

            if ($(elem).hasClass("bp__wishlist")) {
                event.stopPropagation();
                event.preventDefault();
                toggleFavorite(lot, elem, currentAuctionNumber);
            }
        });
        $("body").on("click", ".modal-open", function (event) {
            var $this = $(this),
                target = $this.attr("data-micromodal-trigger"),
                parentModal = $this.parents(".bp-modal");

            if (parentModal.length) {
                MicroModal.close(parentModal.attr("id"));
            }

            MicroModal.show(target, microModalInitConfig());
        });
        $("body").on("click", ".click-action", function (event) {
            var $this = $(this),
                target = $this.attr("data-trigger"),
                parentModal = $this.parents(".bp-modal");

            if (parentModal.length) {
                MicroModal.close(parentModal.attr("id"));
            }

            $("#" + target).trigger("click");
        });

        function loadMore() {
            var loadMoreButton = $(".bt-wi-lots_more .btn"),
                bgColor = $(".bt-wi-lots_wrp").attr("data-bg-color");

            if (loadMoreButton.length) {
                loadMoreButton.on("click", function (event) {
                    event.preventDefault();
                    var $this = $(this),
                        parent = $this.parents(".bt-wi-lots_wrp"),
                        count = parent.find(".bp-lots .bp-lot").length;
                    $.ajax({
                        type: "post",
                        dataType: "json",
                        url: window.wp_data.ajax_url,
                        data: {
                            action: "do_lot_list",
                            security: window.wp_nonce,
                            count: count
                        }
                    }).done(function (response) {
                        loadTemplate(parent.find(".bp-lots"), "shortcode-lot", {
                            lots: response.data.lots,
                            currency: currencySymbol,
                            bgColor: bgColor
                        }, false, function () {
                        }, true);
                        count = parent.find(".bp-lots .bp-lot").length;

                        if (count >= response.data.total) {
                            parent.find(".bt-wi-lots_more").addClass(window.bs_data.hidden_class);
                        }
                    }).fail(function () {
                        console.error("Fatal error");
                    });
                });
            }
        }

        function printNoticeBanner() {
            var htmlTemplate = document.getElementById("oldest-browser-template").innerHTML,
                data = {
                    message: window.bs_lang.oldest_browser_text,
                    linkMessage: window.bs_lang.oldest_browser_link_text,
                    link: window.bs_data.link_on_not_supported_browsers
                };
            htmlTemplate = _.template(htmlTemplate);
            $("body").append(htmlTemplate(data));
        }

        function ie11supportDisabled() {
            if (auctionforgeDetectIE()) {
                printNoticeBanner();
            }
        }

        function incrementTable() {
            $("#incrementTable, [href='#incrementTable']").on("click", function (event) {
                MicroModal.show("modal-steps", microModalInitConfig());
                loadTemplate("#modal-steps-content", "increment-tables-template", {
                    data: bidspiritApi.getAuctionInfo().increments,
                    currency: currencySymbol
                }, true);
            });
        }

        tabs();
        spoiler();
        select2ToolsInit();
        loadMore();
        singleLotAction();
        onPageAction();
        incrementTable();
        ie11supportDisabled();
    });
})(jQuery);

function noticeSwall(type, title, message, params, callback) {
    if (params === undefined) {
        params = {};
    }

    var conf = {
        icon: type,
        title: title,
        text: message
    };
    conf = jQuery.extend({}, conf, params);
    Swal.fire(conf).then(function (result) {
        if (result.isConfirmed && callback !== undefined) {
            callback();
        }
    });
}

function getLeftDate(eventDate) {
    var outputDays = jQuery("#auctionStartTimer .outputDays"),
        outputHours = jQuery("#auctionStartTimer .outputHours"),
        nowDate = new Date(),
        archiveDate = timeShift(new Date(eventDate)),
        result = archiveDate.getTime() - nowDate.getTime() + 1000,
        hours = Math.floor(result / 1000 / 60 / 60 % 24),
        days = Math.floor(result / 1000 / 60 / 60 / 24);

    if (result < 0) {
        jQuery("#auctionStartTimer").hide();
    } else {
        outputDays.text(days);
        outputHours.text(hours);
    }
}

function smartCut(text, limit) {
    if (text === undefined) {
        return "";
    }

    text = text.replace(/<\/?[^>]+(>|$)/g, "");
    var array = text.split(" ").slice(0, limit);
    return array.join(" ");
}

function microModalInitConfig() {
    return {
        onShow: modal => {
            console.info(modal);
        },
        onClose: modal => {
            console.info(modal);
        },
        debugMode: false
    };
}

function formattedPrice(price, currencySymbol, secondPrice, showDecimals) {
    if (currencySymbol === undefined) {
        currencySymbol = window.bidSpiritCurrency;
    }

    if (secondPrice !== undefined && secondPrice === true) {
        let auctionInfo = bidspiritApi.getAuctionInfo();
        if (auctionInfo.secondCurrency !== undefined && auctionInfo.secondCurrencyRate !== undefined) {
            secondPrice = " (" + formattedPrice((Number(price) * auctionInfo.secondCurrencyRate).toFixed(2), auctionInfo.secondCurrency) + ")";
        } else {
            secondPrice = "";
        }
    } else {
        secondPrice = "";
    }
    try {
        if (price === undefined || price === null || (typeof price === 'number' && isNaN(price)) || price === 'NaN') {
            price = 0;
        }
        var _fd = (showDecimals === true) ? 2 : 0;
        price = Number(String(price).replace(/[^0-9.-]/g, '')).toLocaleString('en-US', {minimumFractionDigits: _fd, maximumFractionDigits: _fd});

        switch (window.bidSpiritLang) {
            case "ru":
                return price.replace(/(\,)/, " ") + " " + currencySymbol + secondPrice;

            default:
                return currencySymbol + price + secondPrice;
        }
    } catch (e) {
        return currencySymbol + price + secondPrice;
    }
}

function auctionforgeDetectIE() {
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf("MSIE ");

    if (msie > 0) {
        // IE 10 or older => return version number
        return true;
    }

    var trident = ua.indexOf("Trident/");

    if (trident > 0) {
        // IE 11 => return version number
        return true;
    }

    var edge = ua.indexOf("Edge/");

    if (edge > 0) {
        // Edge (IE 12+) => return version number
        return false;
    }

    return false;
}

function bp_t(phrase) {
    var key = phrase.toLowerCase().replace(/(\s)+/gm, "_");
    if (window.bs_lang[key] !== undefined) {
        return window.bs_lang[key];
    } else {
        return phrase;
    }
}

function bpGetQueryParams(qs) {
    var searchParams = new URLSearchParams(window.location.search);
    return searchParams.get(qs);
}

function bpIsset(variable) {
    return typeof variable != "undefined" && variable !== null;
}

function bpYoutubeIDParser(url) {
    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/;
    var match = url.match(regExp);
    return match && match[7].length == 11 ? match[7] : false;
}

function getTimeZoneFromUser() {
    return Intl.DateTimeFormat().resolvedOptions().timeZone;
}

function convertTZ(date, tzString) {
    return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", {
        timeZone: tzString
    }));
}

function getLocaleFromUser() {
    return Intl.DateTimeFormat().resolvedOptions().locale;
}

function timeShift(deadline, isDTS) {
    function createDateAsUTC(date) {
        return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
    }

    Date.prototype.addHours = function (hours) {
        var date = new Date(this.valueOf());
        date.setHours(date.getHours() + hours);
        return date;
    };

    var baseTimeZone = parseInt(window.timeZone),
        baseTimeZoneName = window.timeZoneName;

    if (bpIsset(baseTimeZoneName) && bpIsset(window.timeZoneName) !== "") {
        deadline = createDateAsUTC(new Date(new Date(deadline).toLocaleString("en-US", {
            timeZone: "UTC"
        })));
        return deadline;
    } else {
        var timeZone = deadline.getTimezoneOffset() / 60 * -1 - baseTimeZone;
        return new Date(deadline.getTime()).addHours(timeZone);
    }
}

function isDisabledReadNotice() {
    return false;
}

(function ($) {
    function metaSlider() {
        if ($(".bt-wi-slider .swiper-container").length) {
            new SwiperBP(".bt-wi-slider .swiper-container", {
                slidesPerView: 1,
                breakpoints: {
                    320: {
                        slidesPerView: 2
                    },
                    640: {
                        slidesPerView: 3,
                        spaceBetween: 10
                    },
                    990: {
                        slidesPerView: 4,
                        spaceBetween: 15
                    },
                    1200: {
                        slidesPerView: 5,
                        spaceBetween: 20
                    }
                },
                autoplay: {
                    delay: 4000
                }
            });
        }
    }

    function inquiryLot() {
        function decodeHtmlEntities(html) {
            const entities = {
                '&lt;': '<',
                '&gt;': '>',
                '&amp;': '&',
                '&quot;': '"',
                '&#39;': "'",
            };
            return html.replace(/&lt;|&gt;|&amp;|&quot;|&#39;/g, match => entities[match]);
        }

        function fillFiled(inquiryField) {
            inquiryField.each(function (index, elem) {
                var qParam = "";

                try {
                    qParam = decodeHtmlEntities(bpGetQueryParams("bp-inquiry"));
                } catch (e) {
                    console.info(e);
                    qParam = bpGetQueryParams("bp-inquiry");
                }
                $(elem).val(qParam);
            });
        }

        var inquiryField = $(".inquiry-target-field"),
            defaultFields = $(".elementor-form .elementor-field-type-textarea textarea, .wpcf7-form .wpcf7-textarea");

        if (inquiryField.length) {
            fillFiled(inquiryField);
        } else if (defaultFields.length) {
            fillFiled(defaultFields);
        }
    }

    function fallbackCopyTextToClipboard(text) {
        var textArea = document.createElement("textarea");
        textArea.value = text;
        textArea.style.top = "0";
        textArea.style.left = "0";
        textArea.style.position = "fixed";
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();

        try {
            var successful = document.execCommand("copy");
            var msg = successful ? "successful" : "unsuccessful";
            console.info("Fallback: Copying text command was " + msg);
        } catch (err) {
            console.error("Fallback: Oops, unable to copy", err);
        }

        document.body.removeChild(textArea);
    }

    function copyTextToClipboard(text) {
        if (!navigator.clipboard) {
            fallbackCopyTextToClipboard(text);
            return;
        }

        navigator.clipboard.writeText(text);
    }

    function shareLink() {
        var shaleLinkBtn = $(".share-btn__link[data-id=link]");

        if (shaleLinkBtn !== undefined) {
            shaleLinkBtn.on("click", function (event) {
                event.preventDefault();
                var $this = $(this);

                if ($this.hasClass("share-btn__link-active")) {
                    return;
                }

                copyTextToClipboard(window.location);
                $this.html(window.bs_lang.copied).addClass("share-btn__link-active");
                return;
            });
        }
    }

    function countDown() {
        function getTimeRemaining(endtime) {
            var t = Date.parse(endtime) - Date.parse(new Date()),
                index = t <= 0 ? 0 : 1,
                seconds = Math.floor(t / 1000 % 60) * index,
                minutes = Math.floor(t / 1000 / 60 % 60) * index,
                hours = Math.floor(t / (1000 * 60 * 60) % 24) * index,
                days = Math.floor(t / (1000 * 60 * 60 * 24)) * index;
            return {
                total: t,
                days: days,
                hours: hours,
                minutes: minutes,
                seconds: seconds
            };
        }

        function initializeClock(clock, endtime) {
            if (clock) {
                var daysSpan = clock.querySelector(".bp-days");
                var hoursSpan = clock.querySelector(".bp-hours");
                var minutesSpan = clock.querySelector(".bp-minutes");
                var secondsSpan = clock.querySelector(".bp-seconds");

                function updateClock() {
                    var t = getTimeRemaining(endtime);
                    daysSpan.innerHTML = t.days;
                    hoursSpan.innerHTML = ("0" + t.hours).slice(-2);
                    minutesSpan.innerHTML = ("0" + t.minutes).slice(-2);
                    secondsSpan.innerHTML = ("0" + t.seconds).slice(-2);

                    if (t.total <= 0) {
                        clearInterval(timeinterval);
                    }
                }

                updateClock();
                var timeinterval = setInterval(updateClock, 1000);
            }
        }

        var countdown = $(".bp-countdown");

        if (countdown.length) {
            countdown.each(function (index, count) {
                var dateTime = $(count).attr("data-time"),
                    deadline = new Date(Date.parse(dateTime));
                initializeClock(count, timeShift(deadline));
            });
        }
    }

    function getAuctionCarCallback(response) {
        if (_.template !== undefined) {
            var carInfoTemplate = document.getElementById("car-info-template");

            if (!bpIsset(carInfoTemplate)) {
                return;
            }

            var html = _.template(carInfoTemplate.innerHTML),
                additionalInfoBlock = document.getElementById("additional-info-block");

            response = response.response;

            if (response.item !== undefined && response.item.carInfo !== undefined) {
                additionalInfoBlock.innerHTML = html({
                    data: response.item,
                    info: response.item.carInfo
                });
            }
        }
    }

    function getAuctionApertmentCallback(response) {
        if (_.template !== undefined) {
            var apartmentTemplate = document.getElementById("apartment-info-template");

            if (!bpIsset(apartmentTemplate)) {
                return;
            }

            var html = _.template(apartmentTemplate.innerHTML),
                additionalInfoBlock = document.getElementById("additional-info-block");

            response = response.response;

            if (response.item !== undefined && response.item.realEstateInfo !== undefined) {
                additionalInfoBlock.innerHTML = html({
                    data: response.item,
                    info: response.item.realEstateInfo
                });
            }
        }
    }

    function getAuctionIndustrialCallback(response) {
        if (_.template !== undefined) {
            var apartmentTemplate = document.getElementById("industrial-info-template");

            if (!bpIsset(apartmentTemplate)) {
                return;
            }

            var html = _.template(apartmentTemplate.innerHTML),
                additionalInfoBlock = document.getElementById("additional-info-block");

            response = response.response;

            if (response.item !== undefined && response.item.machineInfo !== undefined) {
                additionalInfoBlock.innerHTML = html({
                    data: response.item,
                    info: response.item.machineInfo
                });
            }
        }
    }

    function afterInitAction() {
        let profileLink = $("#bp-profile-link");
    }

    function afterLoginAction() {
        let href = window.location.href.replace(window.location.search, "");
        if (href === window.bs_data.sign_in_permalink) {
            window.location = window.bs_data.link_profile;
        }
    }

    function adminBarTools() {
        function adminBarToolsCallback(response) {
            $("#wp-admin-bar-bp-single-sync a").on("click", function (event) {
                event.preventDefault();
                let data = response.response.item;
                $.ajax({
                    url: "/wp-json/plugin/v1/sync-lot/",
                    type: "POST",
                    dataType: "json",
                    data: {
                        item: data,
                        auctionId: data.auctionId,
                        itemIndex: data.itemIndex,
                        language: data.lang,
                        sessionId: bidspiritApi.getBidspiritSessionId()
                    }
                }).done(function (response) {
                    noticeSwall("info", window.bs_lang.lot_sync_is_queued);
                }).fail(function (response) {
                    noticeSwall("error", window.bs_lang.not_found);
                }).always(function () {
                });
            });
        }

        if (document.body.classList.contains("admin-bar") && document.body.classList.contains("admin-bar")) {
            $(window).on("bp:get-auction-item", adminBarToolsCallback);
        }
    }

    function menuSwitcher(langCode) {
        let pllSwitch = jQuery(".bt-header-row ul.cpel-switcher__list:not(.cpel-switcher__lang--active)"),
            langSwitch = pllSwitch.find('a[lang^="' + langCode + '"]').attr("href");
        if (langSwitch !== undefined) {
            window.location.href = langSwitch;
        }
    }

    $(document).ready(function () {
        metaSlider();
        inquiryLot();
        shareLink();
        countDown();
        adminBarTools();
        $(window).on("bp:get-auction-item", getAuctionCarCallback);
        $(window).on("bp:get-auction-item", getAuctionApertmentCallback);
        $(window).on("bp:get-auction-item", getAuctionIndustrialCallback);
        $(window).on("bp:after-init", afterInitAction);
        $(window).on("bp:after-login", afterLoginAction);
    });
})(jQuery);