var app = angular.module("myApp", ["ngSanitize"]).filter("safeHtml", function ($sce) {
    return function (val) {
        return $sce.trustAsHtml(val);
    };
});
app.controller("CartController", function ($scope, $http) {
    $scope.cart = false;
    $scope.loading = false;
    $scope.items = [];
    $scope.customer = {
        token: token
    };
    $scope.tenancyToken = tenancyToken;
    $scope.user = user;
    $scope.totalAmount = 0;
    $scope.currentCartItem = {};
    $scope.currentVariant = {};
    $scope.variantOptionSelected = {};
    $scope.variantImageSelected = {};
    $scope.newItem = {};
    $scope.currentProduct = {};
    $scope.variants = {};
    $scope.products = {};
    $scope.variantBases = {};
    $scope.groupVariants = [];
    $scope.variantsStatistic = [];
    $scope.ignoreOptionIds = ignoreOptionIds;
    $scope.discountValue = 0;
    $scope.firstLoadingCart = true;
    $scope.totalCartItem = localStorage.getItem("cart-item") ? localStorage.getItem("cart-item") : 1;
    $scope.textBusinessDays = textBusinessDays
    $scope.deliveryText = deliveryText;
    $scope.monthNames = monthNames;
    $scope.copyText = copyText;
    $scope.invalidQuantityText = invalidQuantityText;
    $scope.addedToCartText = addedToCartText;
    $scope.confirmRemoveItemText = confirmRemoveItemText;
    $scope.coppiedText = coppiedText;
    $scope.removeItemText = removeItemText;
    $scope.textBuyDesign = textBuyDesign;
    $scope.countries = [];
    $scope.selectedCountry = {
        "id": 226,
        "iso": "US",
        "name": "UNITED STATES",
        "nicename": "United States"
    };
    $scope.tmpSelectedCountry = {};
    $scope.shipping_fee = 0;
    $scope.filterCountry = "";
    $scope.isSearch = false;
    $scope.designFee = parseFloat(designFee);
    $scope.includeDesignFee = parseFloat(includeDesignFee);
    $scope.sameInCartText = sameInCartText;
    $scope.freeshipPackageProduct = {};
    $scope.printLocations = printLocations;
    $scope.customerRewards = {
        rewardsPercent: rewardsPercent,
        showRewards: showRewards,
    };
    $scope.showModalRemoveCartItem = false;
    $scope.itemRemove = {};
    $scope.comments = [];
    $scope.isShowLoginModal = false;
    $scope.customerLogin = {};
    $scope.isRegister = false;
    $scope.isSubmitEmail = false;
    $scope.emailLogin = "";
    $scope.isEmptyCart = false;
    $scope.passLogin = "";
    $scope.errorLogin = "";
    $scope.earnPointText = earnPointText;
    $scope.designFeeByProducts = {};
    $scope.pointEarn = 0;
    $scope.showLoyaltyNoti = true;
    $scope.moreAmount = 0;
    $scope.textMoreAmount = moreAmountText;
    $scope.morePoint = 0;
    $scope.configRangeByMarket = [];
    $scope.shippingInfoResponse = [];
    $scope.selectedShippingCart = [];
    $scope.shippingTypeCart = "";
    $scope.shippingCountry = "";
    $scope.paypalAccount = null;
    $scope.totalDesignFee = 0;
    $scope.wishlistItems = [];
    $scope.getPointEarn = function(amount) {
        if ($scope.isChangeCurrency) {
            amount = decimalAdjust('ceil', amount / priceConfig.ratio);
        }

        // Default to 0 points if amount is too small or no config available
        $scope.pointEarn = 0;

        // Return early if amount is too small or configRangeByMarket is not available
        if (!$scope.configRangeByMarket || !$scope.configRangeByMarket.tiers) {
            return;
        }

        // Build thresholds dynamically from configRangeByMarket data
        let thresholds = [];

        // Add flexible tier first (highest threshold)
        if ($scope.configRangeByMarket.flexible_tier) {
            const flexibleTier = $scope.configRangeByMarket.flexible_tier;
            thresholds.push({
                min: flexibleTier.min_amount,
                points: () => Math.round(amount * flexibleTier.cp_per_dollar * 100) / 100
            });
        }

        // Add fixed tiers in descending order
        if ($scope.configRangeByMarket.tiers && Array.isArray($scope.configRangeByMarket.tiers)) {
            // Sort tiers by min_amount in descending order to maintain priority
            const sortedTiers = [...$scope.configRangeByMarket.tiers].sort((a, b) => b.min_amount - a.min_amount);

            sortedTiers.forEach(tier => {
                thresholds.push({
                    min: tier.min_amount,
                    points: () => tier.cp
                });
            });
        }

        // Find the applicable tier (first one where amount >= min)
        const tier = thresholds.find(({ min }) => amount >= min);
        $scope.pointEarn = tier ? tier.points() : 0;
    };

    $scope.checkNotifyMoreAmount = function (amount) {
        // Nếu không có dữ liệu từ configRangeByMarket, không thực hiện gì cả
        if (!$scope.configRangeByMarket || !$scope.configRangeByMarket.tiers) {
            $scope.moreAmount = 0;
            $scope.morePoint = 0;
            return;
        }

        // Tạo thresholds từ dữ liệu trong configRangeByMarket
        let thresholds = [];
        
        // Tạo các tier từ tiers trong configRangeByMarket
        if ($scope.configRangeByMarket.tiers && Array.isArray($scope.configRangeByMarket.tiers)) {
            $scope.configRangeByMarket.tiers.forEach(tier => {
                const target = tier.min_amount;
                const min = Math.round(target * 0.8); // min là 80% của target
                thresholds.push({
                    min: min,
                    target: target,
                    points: tier.cp
                });
            });
        }
        
        // Thêm flexible tier nếu có
        if ($scope.configRangeByMarket.flexible_tier) {
            const flexibleTier = $scope.configRangeByMarket.flexible_tier;
            const target = flexibleTier.min_amount;
            const min = Math.round(target * 0.8);
            const points = Math.round(target * flexibleTier.cp_per_dollar);
            thresholds.push({
                min: min,
                target: target,
                points: points
            });
        }
        
        // Sắp xếp các threshold theo thứ tự tăng dần của min
        thresholds.sort((a, b) => a.min - b.min);
        
        // Tìm threshold phù hợp
        const threshold = thresholds.find(t => amount >= t.min && amount < t.target);
        if (threshold) {
            $scope.moreAmount = $scope.formatPrice(threshold.target - amount, 0, false);
            $scope.morePoint = threshold.points;
        } else {
            $scope.moreAmount = 0;
            $scope.morePoint = 0;
        }
    };

    $scope.eventRemoveCartInsider = function (item) {
        var localeInsider = 'us';
        if (typeof localePrefix !== 'undefined' && localePrefix !== '') {
            localeInsider = localePrefix;
        }
        let {color, size, taxonomy, seller_name} = $scope.getSizeAndColorAndTaxonomy(item.cart_item_insider ?? null);
        let data = {
            type: 'remove_from_cart',
            value: {
                id: 'sku-' + item.product_sku_id,
                name: item.product_name,
                groupcode: localeInsider + '-' + item.product_id,
                taxonomy: taxonomy,
                unit_price: parseFloat(item.high_price),
                unit_sale_price: parseFloat(item.price),
                quantity: parseInt(item.quantity),
                url: item.url,
                color: color ?? "",
                size: size ?? "",
                product_image_url: item.image_url,
                custom: {
                    merchandiser: seller_name,
                    country: localeInsider
                }
            }
        }
        $scope.pushEventToInsider(data);
    }

    $scope.eventViewCartInsider = function() {
        var localeInsider = 'us';
        if (typeof localePrefix !== 'undefined' && localePrefix !== '') {
            localeInsider = localePrefix;
        }
        let data = {
            type: 'cart',
            value: {
                shipping_cost: $scope.shipping_fee,
                total: $scope.getCartAmount(false),
                items: []
            }
        }
        $scope.items.forEach(function(item) {
            let {color, size, taxonomy, seller_name} = $scope.getSizeAndColorAndTaxonomy(item.cart_item_insider ?? null);
            data.value.items.push({
                id: 'sku-' + item.product_sku_id,
                name: item.product_name,
                groupcode: localeInsider + '-' + item.product_id,
                taxonomy: taxonomy,
                unit_price: parseFloat(item.high_price),
                unit_sale_price: parseFloat(item.price),
                quantity: parseInt(item.quantity),
                url: item.url,
                color: color ?? "",
                size: size ?? "",
                product_image_url: item.image_url,
                custom: {
                    merchandiser: seller_name,
                    country: localeInsider
                }
            });
        });
        $scope.pushEventToInsider(data);
    }

    $scope.getSizeAndColorAndTaxonomy = function(dataInsider) {
        let color = '';
        let size = '';
        let taxonomy = [];
        let seller_name = '';
        if (dataInsider) {
            try {
                dataInsider = JSON.parse(dataInsider);
                color = dataInsider.color;
                size = dataInsider.size;
                taxonomy = dataInsider.array_category_name;
                seller_name = dataInsider.seller_name;
            } catch (error) {
            }
        }
        return {color: color, size: size, taxonomy: taxonomy, seller_name: seller_name};
    }

    $scope.pushEventToInsider = function (data) {
        const newEvent = new CustomEvent('eventInsider', {
            detail: data,
            bubbles: true,
            cancelable: true
        });
        document.dispatchEvent(newEvent);
    }

    $scope.getCart = function () {
        return new Promise(function (resolve) {
            var locale = '';
            if (typeof localePrefix !== 'undefined' && localePrefix !== '') {
                locale = `/${localePrefix}`;
            }
            $scope.cart = false;
            $scope.loading = true;
            var url = `/cart/get-cart-items`;
            $http({
                method: "GET",
                url: url,
            }).then(
                function successCallback(response) {
                    response.data.result.forEach(function(item) {
                        item.url = `${siteBaseUrl}${item.url}`;
                    });
                    $scope.originItems = angular.copy(response.data.result);
                    let feeBuyDesign = 0;
                    let items = response.data.result;
                    for (let key in items) {
                        if (items[key] && items[key].id) {
                            items[key].is_wishlist = false;
                            if (items[key].name_variant != "" && items[key].product_name && items[key].product_name.includes(", " + items[key].name_variant)) {
                                items[key].product_name = items[key].product_name.replace(", " + items[key].name_variant, "");
                            }
                            try {
                                let configurations = JSON.parse(items[key].configurations);
                                items[key].configurationsValue = items[key].configurations;
                                items[key].configurations = {};
                                for (let i in configurations) {
                                    if (typeof configurations[i] == 'string' || typeof configurations[i] == 'number') {
                                        items[key].configurations[i] = configurations[i];
                                    }
                                }
                                if (configurations && configurations.disable_make_change) {
                                    items[key].disable_make_change = true;
                                }
                                if (configurations && configurations.design_fee) {
                                    feeBuyDesign += parseFloat(configurations.design_fee);
                                }
                                if (configurations && configurations.buy_design == 1) {
                                    items[key].buy_design = true;
                                }
                                if (configurations && configurations.hire_designer != undefined) {
                                    items[key].hire_designer = configurations.hire_designer;
                                }
                                if (configurations.edit_url) {
                                    items[key].url = configurations.edit_url.url;
                                }
                                if (configurations.price_addtocart) {
                                    items[key].disable_make_change = true;
                                }
                                if (configurations.price_by_quantity && configurations.price_by_quantity.discount == 1) {
                                    $scope.isBulkOrder = true;
                                }
                                if (configurations["Preview url"]) {
                                    items[key].preview_url = configurations["Preview url"]['image_url'];
                                }
                                if (configurations.config_by_print_location && Object.keys(configurations.config_by_print_location).length) {
                                    items[key].print_location_3d = Object.keys(configurations.config_by_print_location).map(text => cartTranslateText[text]).join(', ');
                                }
                            } catch (error) {
                                console.log(error);
                                items[key].configurations = {};
                            }
                        }
                    }
                    var lcpBox = document.getElementById('cart-default-lcp');
                    if (lcpBox) {
                        lcpBox.remove();
                    }
                    $scope.items = items;
                    $scope.cart = response.data;
                    $scope.totalDesignFee = feeBuyDesign;
                    let result = $scope.cart.sub_total + feeBuyDesign;
                    for (let index = 0; index < $scope.items.length; index++) {
                        const element = $scope.items[index];
                        element.total_amount = element.quantity * element.price;
                    }
                    if (priceConfig) {
                        result = 0;
                        for (let index = 0; index < $scope.items.length; index++) {
                            const element = $scope.items[index];
                            let priceItem = parseFloat(element.price);
                            priceItem += parseFloat(priceConfig.adding_price);
                            priceItem *= parseFloat(priceConfig.ratio);
                            element.total_amount = element.quantity * decimalAdjust('ceil', priceItem);
                            result += element.total_amount;
                        }
                        if (feeBuyDesign > 0) {
                            result += decimalAdjust('ceil', feeBuyDesign * parseFloat(priceConfig.ratio));
                            $scope.totalDesignFee = decimalAdjust('ceil', feeBuyDesign * parseFloat(priceConfig.ratio));
                        }
                    }
                    $scope.cart.sub_total_origin = $scope.cart.sub_total
                    $scope.cart.sub_total = result;
                    $scope.totalAmount = result;
                    $scope.loading = false;
                    $scope.firstLoadingCart = false;
                    $scope.isEmptyCart = ($scope.items.length == 0) ? true : false;
                    $scope.getWishlistItems();
                    resolve();
                },
                function errorCallback(response) {
                    resolve();
                }
            );
        });
    };

    $scope.addBodyClass = function(event) {
        var target = event.currentTarget.getAttribute('data-target');
        if (target) {
            document.body.classList.add(target);
        }
    };

    $scope.clearBodyClassAndStyle = function() {
        document.body.className = '';
        document.body.removeAttribute('style');
    };

    $scope.removeAllBodyClasses = function() {
        document.body.className = '';
    };

    $scope.getCustomerToken = () => {
        return new Promise(function(resolve) {
            var locale = '';
            if (typeof localePrefix !== 'undefined' && localePrefix !== '') {
                locale = `/${localePrefix}`;
            }
            $scope.loading = true;
            var url = `${locale}/cart/get-customer-token?ignore_localization=1`;
            $http({
                method: "GET",
                url: url,
            }).then(
                function successCallback(response) {
                    if (response.data.status == "successful") {
                        $scope.customer.token = response.data.result;
                    }
                    $scope.loading = false;
                    resolve();
                },
                function errorCallback(response) {
                    resolve();
                }
            );
        });
    }

    $scope.getConfigRangeByMarket = () => {
        return new Promise(function(resolve, reject) {
            $http({
                method: "GET",
                url: '/cart/get-config-range-by-market',
            }).then(async function successCallback(response) {
                if (response.data.status == "successful") {
                    $scope.configRangeByMarket = response.data.result;
                }
                resolve();
            }).catch(function errorCallback(error) {
                reject();
            });
        });
    }

    $scope.formatPrice = function(price, numberAdd = 1, format = true) {
        if (format && price != 0) {
            if (priceConfig) {
                price = (parseFloat(price) + parseFloat(priceConfig.adding_price) * numberAdd) * parseFloat(priceConfig.ratio);
            }
            price = decimalAdjust('ceil', price);
        }
        return formatPrice(price, priceTempate);
    };
    function decimalAdjust(type, value) {
        let matches = priceTempate.match(/{money}{([^a-zA-z0-9]+)}{([0-9]+)}/);
        let exp = -2;
        if (matches.length == 3) {
            exp = parseInt(matches[2] * (matches[2] ? -1 : 1));
        }
        // If the exp is undefined or zero...
        if (typeof exp === 'undefined' || +exp === 0) {
        return Math[type](value);
        }
        value = +value;
        exp = +exp;
        // If the value is not a number or the exp is not an integer...
        if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
            return NaN;
        }
        // Shift
        value = value.toString().split('e');
        value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
        // Shift back
        value = value.toString().split('e');
        return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
    }


    $scope.getImageCdn = window.getImageCdn;

    $scope.getDiscountInfo = () => {
        $http({
            method: "GET",
            url: '/discount/total',
        }).then(function successCallback(response) {
            if (response.data.status == "successful") {
                let discount = 0;
                let discountItem = response.data.result;
                for (const [key, value] of Object.entries(discountItem)) {
                    discount += parseFloat(value.total_discount)
                }
                if (discount > 0) {
                    $scope.discountValue = discount;
                }
            }
        }).catch(function errorCallback(error) {
        });
    }

    $scope.getCountries = function () {
        return new Promise(function (resolve) {
            $scope.loading = true;
            $http({
                method: "GET",
                url: base_api_url + "/countries?page_size=-1",
            }).then(
                function successCallback(response) {
                    $scope.countries = response.data.result;
                    let customerCountry = {
                        "id": 226,
                        "iso": "US",
                        "name": "UNITED STATES",
                        "nicename": "United States"
                    };
                    for (let index = 0; index < $scope.countries.length; index++) {
                        const element = $scope.countries[index];
                        if (element.iso == countryByIp.toUpperCase()) {
                            customerCountry = element;
                        }
                    }
                    $scope.selectedCountry = customerCountry;
                    $scope.loading = false;
                    resolve();
                },
                function errorCallback(response) {
                    $scope.loading = false;
                    resolve();
                }
            ).catch(function errorCallback(error) {
                $scope.loading = false;
                resolve();
            });
        });
    };

    $scope.initial = async () => {
        await $scope.getCustomerToken();
        await $scope.getConfigRangeByMarket();
        await Promise.all([
            $scope.getCart(),
            $scope.getFreeShippingInfo(),
            $scope.getCountries()
        ]);
        $scope.getFreeShippingInfo()
        $scope.getProductsDesignWatermark();
        $scope.getSameCartItem();
        $scope.getDesignFee();
        let customerInfo = JSON.parse(localStorage.getItem("customerInfo") ? localStorage.getItem("customerInfo") : "{}");
        if (customerInfo.country) {
            $scope.selectedCountry = customerInfo.country;
        }
        $scope.findFreeshipPackageProduct();
        window.addEventListener('change-cart', async function (event, data) {
            if (event.detail) {
                $scope.loadingRemoveItem = true;
                localStorage.setItem("change-cart", Date.now());
                await Promise.all([
                    $scope.getCart(),
                    $scope.getFreeShippingInfo()
                ]);
                $scope.getFreeShippingInfo()
                $scope.getProductsDesignWatermark();
                $scope.getSameCartItem();
                $scope.getDesignFee();
                if (useDiscount && useDiscountCart == 1) {
                    $scope.getDiscountCartInfo();
                    $scope.getDiscountInfo();
                }
                await $scope.getShippingInfo();
                $scope.$applyAsync(function () {
                    $scope.loadingRemoveItem = false;
                })
            }
        });
        $(window).on("storage", async function (e) {
            let storageEvent = e.originalEvent;
            if (storageEvent.key == "change-cart") {
                $scope.loadingRemoveItem = true;
                await Promise.all([
                    $scope.getCart(),
                ]);
                $scope.getProductsDesignWatermark();
                $scope.getSameCartItem();
                if (useDiscount && useDiscountCart == 1) {
                    $scope.getDiscountCartInfo();
                    $scope.getDiscountInfo();
                }
                await $scope.getShippingInfo();
                $scope.$applyAsync(function () {
                    $scope.loadingRemoveItem = false;
                })
            }
        });
        if (useDiscount && useDiscountCart == 1) {
            $scope.getDiscountCartInfo();
            $scope.getDiscountInfo();
        }
        await $scope.getShippingInfo();
        // if (usePaypalExpressCheckout == 1) {
        //     $scope.showPaypal();
        // }
        $scope.eventViewCartInsider();
    }

    
    $scope.getDiscountCartInfo = () => {
        $.ajax({
            url: '/discount/cart/info'
        }).done(function(response) {
            if (response.status == 'successful') {
                const items = response.result;
                $(".buy-more-text").text("");
                $(".buy-more-text-apply").text("");
                items.forEach(element => {
                    for (let index = 0; index < $(`div[data-product-id='${element.product_id}']`).length; index++) {
                        const item = $(`div[data-product-id='${element.product_id}']`)[index];
                        $(item).find(".buy-more-text-title").text("");
                        $(item).find(".buy-more-text").text(element.message);
                        $(item).find(".shopcart-discount-code").html("");
                        if (element.messageApply) {
                            // copy code action
                            $(item).find(".buy-more-text-apply").text(element.messageApply);
                            let html = "";
                            html += `
                                <div class="buy-more-text-apply discount-text" style="color: #ff7300;">
                                    ${element.messageApply}
                                </div>`;
                            if (element.code && element.code != "") {
                                html += `
                                    <span class="discount-icon" data-code="${element.code}">
                                        <svg width="24" height="24" viewBox="0 0 24 24" role="presentation">
                                            <g fill="currentColor">
                                                <path d="M10 19h8V8h-8v11zM8 7.992C8 6.892 8.902 6 10.009 6h7.982C19.101 6 20 6.893 20 7.992v11.016c0 1.1-.902 1.992-2.009 1.992H10.01A2.001 2.001 0 018 19.008V7.992z"></path>
                                                <path d="M5 16V4.992C5 3.892 5.902 3 7.009 3H15v13H5zm2 0h8V5H7v11z"></path>
                                                </g>
                                            </svg>
                                        <span class="copy-text">
                                            <small class="copy-action">
                                                ${$scope.copyText}
                                            </small>
                                            <small class="copy-done">
                                                ${$scope.coppiedText}
                                            </small>
                                        </span>
                                    </span>
                                `;
                            }
                            $(item).find(".shopcart-discount-code").html(html);
                        }
                        if (element.discount_title != "") {
                            $(item).find(".buy-more-text-title").text('(' + element.discount_title + ')');
                        }
                    }
                });
            }
        })
    }

    $scope.changeQuantity = (item, quantity, type) => {
        quantity = parseInt(quantity);
        if (type == 'increase') {
            quantity += 1;
        } else {
            quantity -= 1;
        }
        if (quantity < 0) {
            quantity = 1;
        }
        if (quantity > 1000) {
            quantity = 1000;
        }
        if (quantity == 0) {
            $scope.openModalRemoveCartItem(item, 1);
        } else {
            $scope.updateCartItem(item, quantity, item.configurationsValue);
        }
    }

    $scope.changeCustomQuantity = (item, quantity) => {
        quantity = parseInt(quantity);
        if (quantity < 0) {
            quantity = 1;
        }
        if (quantity > 1000) {
            quantity = 1000;
        }
        if (quantity == 0) {
            console.log(item)
            for (let index = 0; index < $scope.originItems.length; index++) {
                const element = $scope.originItems[index];
                if (element.id == item.id) {
                    $scope.openModalRemoveCartItem(item, element.quantity);
                }
            }
        } else {
            $scope.updateCartItem(item, quantity, item.configurationsValue);
        }
    }

    $scope.updateCartItem = (item, quantity, configurations = null) => {
        $scope.loading = true;
        $scope.loadingRemoveItem = true;
        let data = {
            id: item.id,
            quantity: quantity,
        }
        if (configurations != null) {
            data.configurations = configurations;
        }
        $http({
            method: "POST",
            url: '/cart/update-cart-item',
            data : data
        }).then(async function successCallback(response) {
            if (response.data.status == "successful") {
                window.dispatchEvent(new CustomEvent('change-cart', {detail: {showCart: false}}));
            }
            $scope.$applyAsync(function () {
                $scope.loading = false;
                $scope.loadingRemoveItem = false;
            })
            
        }).catch(function errorCallback(error) {
            $scope.loading = false;
            $scope.loadingRemoveItem = false;
        });
    }

    $scope.closeLoyaltyNoti = function() {
        $scope.showLoyaltyNoti = false;
    };

    function getCartItems() {
        var locale = '';
        if (typeof localePrefix !== 'undefined' && localePrefix !== '') {
            locale = '/' + localePrefix;
        }
        var getCartReqParams = {
            url: '/cart/get-cart-items',
            method: 'GET'
        };
        $.ajax(getCartReqParams)
            .done(function (result) {
                if (result.status == 'successful') {
                    $("#list-cart-items").html("");
                    $(".mini-cart-list").show();
                    $("#cart-error").hide();
                    $(".js-mini-cart-count").hide();
                    var html = "";
                    var quantity = 0;
                    localStorage.setItem("cart-item", result.result.length);
                    result.result.forEach((element) => {
                        quantity += parseInt(element.quantity);
                        if (element.configurations) {
                            try {
                                let configurations = JSON.parse(element.configurations);
                                if (configurations.edit_url) {
                                    element.force_url = configurations.edit_url.url;
                                }
                            } catch (error) {

                            }
                        }
                        html += `
                        <a class="mini-cart-item flex-box" href="${locale}${element.url}">
                            <img src="${getImageCdn(element.image_url, 130, 0)}" alt="" referrerpolicy="no-referrer">
                            <div class="mini-cart-content">
                                <div class="mini-cart-head">
                                    ${element.product_name}
                                </div>
                                <div class="mini-cart-info flex-box align-c ">
                                    <span class="new-price">${$scope.formatPrice(element.price)}
                    `;
                        if (element.high_price && element.high_price > element.price) {
                            html += `<span class="discount-price" style="text-decoration: line-through;">${$scope.formatPrice(element.high_price)}</span>`
                        }
                        html += `</span><span style"color: red;">&times;</span>
                                        <span class="quantity-mini-cart"> ${element.quantity}</span>
                                    </div>
                                </div>
                            </a>
                    `;
                    });
                    $("#list-cart-items").append(html);
                    $(".js-mini-cart-count").text(parseInt(quantity));
                    if (parseInt(quantity) > 0) {
                        $(".js-mini-cart-count").show();
                    }
                    $(".cart-icon").replaceWith($(".cart-icon").clone());
                    $(".cart-icon").click(function (event) {
                        event.stopPropagation();
                        $(".mini-cart-contain").toggle();
                        $("#list-cart-items").html("");
                        $("#cart-error").hide();
                        if (parseFloat(quantity) > 0) {
                            $(".mini-cart-list").show();
                            $("#list-cart-items").append(html);
                        } else {
                            $("#cart-error").show();
                        }
                    });
                }
            });
    }

    $scope.range = function (min, max, step) {
        step = step || 1;
        var input = [];
        for (var i = min; i <= max; i += step) {
            input.push(i);
        }
        return input;
    };

    $scope.buildShippingInfo = (result) => {
        let dataShipping = result;
        let htmlFreeShip = "";
        let hasText = false;
        dataShipping.forEach(shipping => {
            shipping.cartItems = [];
            if ($scope.items.length > 0) {
                $scope.items.forEach(element => {
                    if (shipping.cart_item_id.includes(element.id)) {
                        shipping.cartItems.push(element);
                    }
                });
            }
            shipping.selectedShipping = shipping.shipping_info[0];
            shipping.shipping_info.forEach(element => {
                let minDate = new Date();
                let maxDate = new Date();
                minDate.setDate(minDate.getDate() + parseInt(element.shipping_min_time));
                maxDate.setDate(maxDate.getDate() + parseInt(element.shipping_max_time));
                element["textBusinessDays"] = $scope.textBusinessDays.replace("#date", element.shipping_min_time + "-" + element.shipping_max_time);
                element["minDateString"] = $scope.monthNames[minDate.getMonth()].replace("#date", minDate.getDate());
                element["maxDateString"] = $scope.monthNames[maxDate.getMonth()].replace("#date", maxDate.getDate());
                element["default_shipping_fee"] = element.shipping_fee;
                if (element["type"] == "standard") {
                    for (let i = 0; i < element["additional_info"].length; i++) {
                        const info = element["additional_info"][i];
                        if (parseFloat(info.fee_limit) > 0 && parseFloat(info.fee_if_limit) == 0 && false) {
                            htmlFreeShip += `<div style="font-weight: 400 !important;"><span style="font-weight: 500;">Free Shipping</span>` + " on orders over " + `<span style="font-weight: 500;">` + $scope.formatPrice(parseFloat(info.fee_limit), 0, true) + "</span> " + `(${info.cate_name})</div>`
                        }
                        if (parseFloat(info.adding_fee) == 0 && info.cate_name == "Stickers" && !hasText) {
                            hasText = true;
                            htmlFreeShip += `<div style="font-weight: 400 !important;"><span style="font-weight: 500;">No extra shipping fee</span>` + " for additional items " + `(${info.cate_name})</div>`
                        }
                    }
                }
            });
        });
        $(".cart-buy-more").html(htmlFreeShip);
        $scope.shippingInfos = dataShipping;
        if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
            $scope.$apply();
        }
        let listApply = [];
        $scope.shippingInfos.forEach(element => {
            if (!listApply[element.selectedShipping.id]) {
                listApply[element.selectedShipping.id] = [];
            }
            var listNewApply = [];
            for (const [key, applyItem] of Object.entries(element.selectedShipping.apply_config_item)) {
                if (listApply[element.selectedShipping.id].includes(applyItem.id)) {
                    element.selectedShipping.shipping_fee = element.selectedShipping.default_shipping_fee - parseFloat(applyItem.default_shipping_fee) + parseFloat(applyItem.default_adding_item);
                }
                listNewApply.push(applyItem.id);
            }
            listApply[element.selectedShipping.id] = listApply[element.selectedShipping.id].concat(listNewApply);
        });
        $scope.deliveryTextShow = $scope.deliveryText.replace("#country", "<b>" + $scope.selectedCountry.nicename + "</b>");
        $scope.getShippingFeeV2();
    };

    $scope.openSelectCountry = () => {
        $scope.countries.forEach(element => {
            if (element.id == $scope.selectedCountry.id) {
                $scope.tmpSelectedCountry = element;
            }
        });
        $scope.isShowSelectCountry = true;
        $scope.listSearchCountries = $scope.countries;
        setTimeout(() => {
            $(".filter-country").focus();
        }, 300);
    }

    $scope.saveSelectCountry = () => {
        $scope.selectedCountry = $scope.tmpSelectedCountry
        $scope.isShowSelectCountry = false;
        let customerInfo = {};
        customerInfo.country = $scope.selectedCountry;
        localStorage.setItem("customerInfo", JSON.stringify(customerInfo));
        $scope.deliveryTextShow = $scope.deliveryText.replace("#country", $scope.selectedCountry.nicename);
        $scope.getShippingInfo();
    }

    $scope.closeSelectCountry = () => {
        $scope.isShowSelectCountry = false;
    }

    $scope.getShippingInfo = async (countryId = null) => {
        $scope.loading = true;
        if (!$scope.selectedCountry || !$scope.selectedCountry.id) {
            $scope.loading = false;
            return;
        }
        let url = base_api_url + "/shipping-fee/item/info?token=" + $scope.customer.token;
        if (countryId) {
            url += "&location_id=" + countryId;
        } else {
            url += "&location_id=" + $scope.selectedCountry.id;
        }
        if ($scope.user && $scope.user.id) {
            url += "&customerId=" + $scope.user.id;
        }
        if ($scope.tenancyToken) {
            url += "&tenancyToken=" + $scope.tenancyToken;
        }
        await $http({
            method: "GET",
            url: url,
        }).then(function successCallback(response) {
            if (response.data.status == "successful") {
                $scope.shippingInfoResponse = angular.copy(response.data.result);
                $scope.buildShippingInfo(response.data.result);
            }
            $scope.loading = false;
        }, function errorCallback(response) {
        }).catch(function errorCallback(error) {
        });
    }

    $scope.getShippingFeeV2 = () => {
        let shippingFee = 0;
        $scope.shippingInfos.forEach(shipping => {
            let element = shipping.selectedShipping;
            if (!priceConfig) {
                shippingFee += parseFloat(element.shipping_fee);
            } else {
                shippingFee += decimalAdjust('ceil', parseFloat(element.shipping_fee) * priceConfig.ratio);
            }
        });
        $scope.shipping_fee = shippingFee;
        $scope.isValidateSpecialShippingFee = false;
        if (typeof useSpecialShippingFee !== "undefined" && useSpecialShippingFee) {
            let subtotal = $scope.cart.sub_total;
            $scope.cart.special_shipping_fee = null;
            $scope.textSpecialShippingFee = "";
            if (shouldUseNewInterface == 'a') {
                if (subtotal >= 50) {
                    $scope.cart.special_shipping_fee = shippingFeeByLevel[0];
                    $scope.isValidateSpecialShippingFee = true;
                } else {
                    $scope.textSpecialShippingFee = textAwayShippingFee.replace("#amount", `<span class="highlight">` + $scope.formatPrice(50 - subtotal, 2, true) + "</span>" );
                    $scope.textSpecialShippingFee = $scope.textSpecialShippingFee.replace("#shipping_fee", $scope.formatPrice(shippingFeeByLevel[0], 2, true));
                }
                if (subtotal >= 100) {
                    $scope.cart.special_shipping_fee = shippingFeeByLevel[1];
                    $scope.isValidateSpecialShippingFee = true;
                } else {
                    if ($scope.textSpecialShippingFee == "") {
                        $scope.textSpecialShippingFee = textAwayShippingFeeLevel2.replace("#amount", `<span class="highlight">` + $scope.formatPrice(100 - subtotal, 2, true) + "</span>" );
                    }
                }
            } else if (shouldUseNewInterface == 'b') {
                $scope.cart.special_shipping_fee = shippingFeeByLevel[0];
                $scope.isValidateSpecialShippingFee = true;
                if (subtotal >= 80) {
                    $scope.cart.special_shipping_fee = shippingFeeByLevel[1];
                    $scope.isValidateSpecialShippingFee = true;
                } else {
                    $scope.textSpecialShippingFee = textAwayShippingFeeLevel2.replace("#amount", `<span class="highlight">` + $scope.formatPrice(80 - subtotal, 2, true) + "</span>" );
                }
            }
            if (priceConfig && $scope.isValidateSpecialShippingFee) {
                $scope.cart.special_shipping_fee = decimalAdjust('ceil', $scope.cart.special_shipping_fee * priceConfig.ratio);
            }
        }
    }

    $scope.getCartAmount = (formatPrice = true) => {
        let amount = 0;
        if ($scope.cart && $scope.cart.sub_total) {
            amount = $scope.cart.sub_total;
            $scope.checkNotifyMoreAmount(amount);
            $scope.getPointEarn(amount);
            if ($scope.isValidateSpecialShippingFee && ($scope.cart.special_shipping_fee || $scope.cart.special_shipping_fee == 0)) {
                amount += $scope.cart.special_shipping_fee;
            } else {
                amount += $scope.shipping_fee;
            }
        }
        if (amount < 0) {
            amount = 0;
        }
        amount = Math.round(amount * 1000) / 1000;
        amount = decimalAdjust('ceil', amount);
        if (formatPrice) {
            amount = $scope.formatPrice(amount, 0, false);
        }
        return amount;
    }

    $scope.searchCountry = () => {
        if ($scope.filterCountry == "") {
            $scope.listSearchCountries = $scope.countries;
        } else {
            $scope.listSearchCountries = $scope.countries.filter(i => i.nicename.toLowerCase().includes($scope.filterCountry.toLowerCase()))
        }
    }

    $scope.selectCountry = (item) => {
        $scope.tmpSelectedCountry = item;
        $scope.isSearch = false;
    }

    $scope.openSearchCountry = () => {
        $scope.isSearch = !$scope.isSearch;
    }
    $scope.buyDesign = (item) => {
        let configurations = JSON.parse(item.configurationsValue);
        if (item.buy_design) {
            configurations.buy_design = 1;
            configurations.design_fee = $scope.designFeeByProducts[item.product_id] + $scope.getIncludeDesignFee(item);
            item.configurations.buy_design = 1
            item.configurations.design_fee = $scope.designFeeByProducts[item.product_id] + $scope.getIncludeDesignFee(item);
        } else {
            delete configurations.buy_design;
            delete configurations.design_fee;
            delete item.configurations.buy_design;
            delete item.configurations.design_fee;
        }
        if ($('#open-buyDesign-' + item.id).is(":checked")) {
            $('#open-buyDesign-' + item.id).prop('checked', false);
        }
        $scope.updateCartItem(item, item.quantity, JSON.stringify(configurations));
    }

    $scope.getIncludeDesignFee = (item) => {
        let result = 0;
        if (item.is_include_design_fee && item.is_include_design_fee == 1) {
            result += $scope.includeDesignFee;
        }
        return result;
    }

    $scope.getProductsDesignWatermark = () => {
        $scope.loading = true;
        let data = [];
        for (let index = 0; index < $scope.items.length; index++) {
            const element = $scope.items[index];
            data.push({
                product_id: element.product_id,
                product_sku_id: element.product_sku_id,
            });
        }
        let url = "/service/pod/preview-design";
        $http({
            method: "POST",
            url: url,
            data: {data: data}
        }).then(function successCallback(response) {
            let listByProduct = [];
            if (response.data.status == 'successful') {
                for (let index = 0; index < response.data.result.length; index++) {
                    const element = response.data.result[index];
                    let key = element.product_id;
                    if (element.product_sku_id) {
                        key += "" + element.product_sku_id;
                    }
                    listByProduct[key] = element
                }
                for (let index = 0; index < $scope.items.length; index++) {
                    const element = $scope.items[index];
                    let key = element.product_id;
                    if (element.product_sku_id) {
                        key += "" + element.product_sku_id;
                    }
                    if (listByProduct[key] && listByProduct[key].design_url) {
                        element.design_url = listByProduct[key].design_url;
                    }
                }
            }
            $scope.loading = false;
        }, function errorCallback(response) {
            $scope.loading = false;
        }).catch(function errorCallback(error) {
            $scope.loading = false;
        });
    }
    $scope.getSameCartItem = () => {
        let data = [];
        let productIds = "";
        for (let index = 0; index < $scope.items.length; index++) {
            const element = $scope.items[index];
            productIds += element.product_id + "";
            if (index < $scope.items.length - 1) {
                productIds += ","
            }
        }
        let url = "/cart/same-item-in-cart?ids=" + productIds;
        $http({
            method: "get",
            url: url,
        }).then(function successCallback(response) {
            let listByProduct = [];
            if (response.data.status == 'successful' && response.data.result > 0) {
                let text = $scope.sameInCartText;
                text = text.replace("#quantity", response.data.result)
                $(".great-taste").text(text);
            }
        }, function errorCallback(response) {
        }).catch(function errorCallback(error) {
        });
    }
    $scope.checkThemeVariantColor = (slug) => {
        let retVal = 'dark';
        if (lightVariantColors.includes(slug)) {
            retVal = 'light';
        }
        return retVal;
    }

    $scope.checkValidDownloadDesign = (item) => {
        let result = false;
        if (item.url.includes("gift-card") || item.url.includes("freeship-package")) {
            result = true;
        }
        return result;
    }

    $scope.getFreeShippingInfo = () => {
        $(".cart-free-ship").html("")
        let url = "/discount/free-ship-info";
        $http({
            method: "get",
            url: url,
        }).then(function successCallback(response) {
            if (response.data.status == 'successful') {
                let code = response.data.result;
                let textFreeship = freeshipText;
                if (code.minimum_require_type == "amount" || code.minimum_require_type == "none") {
                    textFreeship = textFreeship.replace("#amount", $scope.formatPrice(parseFloat(code.minimum_require_value), 0, true)).replace("#code", code.code);
                }
                
                let htmlFreeShip = `<div style="font-weight: 400 !important;">${textFreeship}</div>`
                if ($scope.cart.sub_total_origin <= parseFloat(code.minimum_require_value) * 0.7) {
                    // $(".cart-free-ship").html(htmlFreeShip);
                }
            }
        }, function errorCallback(response) {
        }).catch(function errorCallback(error) {
        });
    }

    $scope.findFreeshipPackageProduct = () => {
        $scope.loading = true;
        $http({
            method: "GET",
            url: '/cart/get-freeship-package-product',
        }).then(async function successCallback(response) {
            if (response.data.status == "successful") {
                $scope.loading = false;
                if (response.data.result.length > 0) {
                    $scope.freeshipPackageProduct = response.data.result[0];
                    for (let index = 0; index < $scope.items.length; index++) {
                        const element = $scope.items[index];
                        if (element.product_id == $scope.freeshipPackageProduct.id) {
                            $scope.isBuyFreeshipPackage = true;
                        }
                    }
                }
            }
        }).catch(function errorCallback(error) {
        });
    }

    $scope.getByField = function (list, fieldName, value) {
        var retVal = null;
        list.forEach(function (item) {
            if (item[fieldName] == value) {
                retVal = item;
            }
        });
        return retVal;
    };

    $scope.openFormChangeVariant = (item) => {
        if (item.disable_make_change) {
            return;
        }
        item.loadingMakeChange = true;
        window.dispatchEvent(new CustomEvent('makeChangeProduct', {
            detail: item
        }));
    }

    window.addEventListener('makeChangeProductDone', function(event, data) {
        let item = angular.copy(event.detail);
        for (let index = 0; index < $scope.items.length; index++) {
            const element = $scope.items[index];
            if (element.id == item.id) {
                element.loadingMakeChange = false;
                $scope.$apply(function() {})
            }
        }
    });

    $scope.openModalRemoveCartItem = (item, oldQuantity = -1) => {
        $scope.oldQuantity = oldQuantity;
        $scope.itemRemove = item;
        $scope.comments = [];
        var rmReqParams = {
            url: base_api_url + '/comment?isParent=1&status=ACTIVE&rating=5&order[created_at]=desc&pageSize=10&pageId=0&targetId=' + item.product_id,
            method: 'GET',
        };
        $scope.loading = true;
        $('body').addClass('open-remove-item-popup').css('overflow', 'hidden');
        $http(rmReqParams).then(async (response) => {
            if (response.data.status == "successful") {
                $scope.showModalRemoveCartItem = true;
                $scope.comments = response.data.result;
            }
            $scope.loading = false;
        }).catch((error) => {
            console.error('Lỗi khi gọi API comment:', error);
            $scope.loading = false;
        });
    }

    async function getTotalProductSale(productId) {
        try {
            const rmReqParams = {
                url: base_api_url + '/product/' + productId,
                method: 'GET',
            };

            const response = await $http(rmReqParams);
            if (response.data.status === "successful") {
                return response.data.result.sold;
            } else {
                return 0;
            }
        } catch (err) {
            console.error('Lỗi trong getTotalProductSale:', err);
            return 0;
        }
    }

    $scope.closeModalRemoveCartItem = () => {
        if ($scope.itemRemove && $scope.itemRemove.id && $scope.oldQuantity != -1) {
            for (let index = 0; index < $scope.items.length; index++) {
                const element = $scope.items[index];
                if (element.id == $scope.itemRemove.id) {
                    element.quantity = $scope.oldQuantity;
                }
            }
        }
        $scope.itemRemove = {};
        $scope.showModalRemoveCartItem = false;
        $('body').removeClass('open-remove-item-popup').css('overflow', '');
    }

    $scope.removeCartItems = (item) => {
        $scope.loadingRemoveItem = true;
        var rmReqParams = {
            url: '/cart/remove-cart-item?ids=' + item.id,
            method: 'DELETE',
        };
        $scope.loading = true;
        $http(rmReqParams).then(async (response) => {
            if (response.data.status == "successful") {
                window.dispatchEvent(new CustomEvent('change-cart', {detail: {showCart: false}}));
                $scope.eventRemoveCartInsider(item);
                $scope.showModalRemoveCartItem = false;
            }

            $scope.$applyAsync(function() {
                $scope.loading = false;
                $scope.loadingRemoveItem = false;
            })
            $('body').removeClass('open-remove-item-popup').css('overflow', '');
        })
    }

    $scope.buildAddPrice = (price, type, categoryIds = []) => {
        let retVal = null;
        let locale = prefixLocaleUrl == "/" ? "us" : prefixLocaleUrl.replace(/\//g, "");
        if ($scope.printLocationsPrice && $scope.printLocationsPrice[type]) {
            if ($scope.printLocationsPrice[type][locale]) {
                let printLocationsPriceByLocale = $scope.printLocationsPrice[type][locale];
                for (let cateId in printLocationsPriceByLocale.category) {
                    let check = categoryIds.find(id => id == cateId);
                    if (check) {
                        retVal = printLocationsPriceByLocale.category[cateId];
                        break;
                    }
                }
                if (!retVal && printLocationsPriceByLocale.default) {
                    retVal = printLocationsPriceByLocale.default;
                }
            }
        }
        let addPrice = 0;
        if (retVal) {
            if (retVal.type == 'percent') {
                addPrice = parseFloat(price) * retVal.value;
            } else {
                addPrice = retVal.value;
            }
        }
        return addPrice;
    }

    $scope.onChangeHireDesigner = (item) => {
        let configurations = {};
        try {
            configurations = JSON.parse(item.configurationsValue);
            configurations = {
                ...configurations,
                ...item.configurations
            }
        } catch (error) {
            
        }
        if (item.hire_designer) {
            configurations.hire_designer = true;
            item.configurations.hire_designer = true;

            configurations.design_fee = window.PodHireDesignerFee;
            item.configurations.design_fee = window.PodHireDesignerFee;

            if (configurations.booking_schedule) {
                configurations.booking_schedule.status = 'ACTIVE';
            }
        } else {
            configurations.hire_designer = false;
            item.configurations.hire_designer = false;

            delete item.configurations.design_fee;
            delete configurations.design_fee;

            if (configurations.booking_schedule) {
                configurations.booking_schedule.status = 'PENDING';
            }
        }
 
        $scope.updateCartItem(item, item.quantity, JSON.stringify(configurations));
    }

    $scope.roundNumber = (number, precision = 0) => {
        return Math.round(number * Math.pow(10, precision)) / Math.pow(10, precision);
    }

    $scope.processCheckout = () => {
        $scope.errorLogin = "";
        let url = checkoutUrl;
        if (document.body.classList.contains('bottomCheck')) {
            document.body.classList.remove('bottomCheck');
        }
        if ((!$scope.user || !$scope.user.id) && false) {
            url = null;
            $scope.isShowLoginModal = true;
            $scope.customerLogin = {};
            $scope.isRegister = false;
            $scope.isSubmitEmail = false;
            $('body').addClass('open-guest-popup').css('overflow', 'hidden');
        }
        if (url) {
            window.location.href = url;
        }
    }

    $scope.closeModalLogin = () => {
        $scope.isShowLoginModal = false;
        $('body').removeClass('open-guest-popup').css('overflow', '');
    }

    $scope.changeEmailLogin = () => {
        $scope.isSubmitEmail = false;
        $scope.errorLogin = "";
    }

    $scope.continueLogin = () => {
        if (!$scope.emailLogin || !validateEmail($scope.emailLogin)) {
            $scope.errorLogin = enterValidEmailText;
            return;
        }
        $scope.isRegister = false;
        $scope.customerLogin = {};
        $scope.isSubmitEmail = true;
        $scope.loading = true;
        $http.post(continueLoginUrl, {
            email: $scope.emailLogin,
            _token: csrfToken,
        }).then(function successCallback(response) {
            if (response.data.status == "successful") {
                if (response.data.result) {
                    $scope.customerLogin = response.data.result;
                    $scope.isRegister = true;
                }
            }
            $scope.loading = false;
        }).catch(function errorCallback(error) {
            $scope.loading = false;
        })
    }

    $scope.login = () => {
        $scope.errorLogin = "";
        if (!$scope.passLogin) {
            $scope.errorLogin = enterEmailText;
            return;
        }
        $scope.loading = true;
        $http.post(loginUrl, {
            email: $scope.emailLogin,
            password: $scope.passLogin,
            _token: csrfToken,
        }).then(function successCallback(response) {
            if (response.data.status == "successful") {
                window.location.href = checkoutUrl + "?internal_source=guest_login";
            } else {
                $scope.errorLogin = response.data.message;
            }
            $scope.loading = false;
        }).catch(function errorCallback(error) {
            $scope.errorLogin = donotMatchText;
            $scope.loading = false;
        })
    }

    $scope.signUp = () => {
        $scope.errorLogin = "";
        if (!$scope.firstNameLogin) {
            $scope.errorLogin = enterValidFirstNameText;
            return;
        }
        if (!$scope.passLogin) {
            $scope.errorLogin = enterPasswordText;
            return;
        }
        if (!$scope.cfPassLogin) {
            $scope.errorLogin = enterConfirmPasswordText;
            return;
        }
        if ($scope.passLogin != $scope.cfPassLogin) {
            $scope.errorLogin = enterMatchPasswordText;
            return;
        }
        $scope.loading = true;
        $http.post(signUpUrl, {
            full_name: $scope.firstNameLogin,
            email: $scope.emailLogin,
            password: $scope.passLogin,
            password_confirmation: $scope.cfPassLogin,
            _token: csrfToken,
        }).then(function successCallback(response) {
            if (response.data.status == "successful") {
                window.location.href = checkoutUrl + "?internal_source=guest_login";
            } else {
                $scope.errorLogin = response.data.message;
            }
            $scope.loading = false;
        }).catch(function errorCallback(error) {
            $scope.errorLogin = donotMatchText;
            $scope.loading = false;
        })
    }

    function validateEmail(email) {
        var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        return re.test(email);
    }

    $scope.getDesignFee = () => {
        let productIds = [];
        for (let index = 0; index < $scope.items.length; index++) {
            const element = $scope.items[index];
            productIds.push(element.product_id);
        }
        $http({
            method: "GET",
            url: '/cart/get-design-fee?ids=' + productIds.join(","),
        }).then(function successCallback(response) {
            $scope.designFeeByProducts = response.data.result;
        }).catch(function errorCallback(error) {
            $scope.loading = false;
        });
    }

    $scope.calculateOtherFee = (otherFeePercent = null) => {
        let fee = 0;
        if ($scope.cart && $scope.cart.sub_total) {
            let amount = parseFloat($scope.cart.sub_total);
            amount = amount + parseFloat($scope.shipping_fee);
            fee = amount * parseFloat(otherFeePercent) / 100;
        }
        fee = decimalAdjust('ceil', fee);

        if (fee < 0) fee = 0;
        return fee;
    }

    $scope.showPaypal = () => {
        paypal.Buttons({
            style: {
                layout: 'vertical',
                shape: 'rect',
                height: typeof heightPaypalButton !== 'undefined' && heightPaypalButton !== '' ? heightPaypalButton : 54,
                tagline: false,
                branding: false,
            },
            createOrder: async function(data, actions) {
                $scope.shippingTypeCart = "standard";
                $scope.shippingCountry = $scope.selectedCountry.iso;
                let shippingOptions = $scope.getPaypalShippingOption($scope.shippingInfoResponse, true);
                let shippingFee = 0;
                for (let index = 0; index < $scope.selectedShippingCart.length; index++) {
                    const element = $scope.selectedShippingCart[index];
                    if (element.amount && element.amount.value) {
                        shippingFee += element.amount.value;
                    } else {
                        shippingFee += element.amount;
                    }
                }
                await $scope.checkTax($scope.selectedCountry.id);
                $scope.shipping_fee = parseFloat(shippingFee);
                let otherTaxFee = 0;
                if ($scope.validTax) {
                    otherTaxFee = $scope.calculateTrumpTax();
                }
                let otherFee = $scope.calculateOtherFee(paypalFee);
                const amount = $scope.cart.sub_total + otherFee + otherTaxFee;
                let orderId = null;
                await $http({
                    method: 'POST',
                    url: base_api_url + '/paypal/express/create',
                    data: { 
                        amount, 
                        shippingOptions,
                        service_token: "megaads@123"
                    }
                }).then(response => {
                    orderId = response.data.order_id;
                    $scope.paypalAccount = response.data.account;
                });
                return orderId;
            },
            onShippingChange: async function(data, actions) {
                let shippingOptions = [];
                let isGetShippingInfo = false;
                let countryId = null;
                if (data.shipping_address && data.shipping_address.country_code != $scope.shippingCountry) {
                    $scope.shippingCountry = data.shipping_address.country_code;
                    for (let index = 0; index < $scope.countries.length; index++) {
                        const element = $scope.countries[index];
                        if (element.iso == data.shipping_address.country_code) {
                            countryId = element.id;
                            break;
                        }
                    }
                    isGetShippingInfo = true;
                    await $scope.getShippingInfo(countryId);
                    await $scope.checkTax(countryId);
                    shippingOptions = $scope.getPaypalShippingOption($scope.shippingInfoResponse, true);
                }
                if (data.selected_shipping_option && data.selected_shipping_option.id && $scope.shippingTypeCart != data.selected_shipping_option.id) {
                    $scope.shippingTypeCart = data.selected_shipping_option.id;
                    $scope.selectedShippingCart = [];
                    $scope.selectedShippingCart.push(data.selected_shipping_option);
                    isGetShippingInfo = true;
                    shippingOptions = $scope.getPaypalShippingOption($scope.shippingInfoResponse);
                }
                if (isGetShippingInfo) {
                    let shippingFee = 0;
                    for (let index = 0; index < $scope.selectedShippingCart.length; index++) {
                        const element = $scope.selectedShippingCart[index];
                        if (element.amount && element.amount.value) {
                            shippingFee += element.amount.value;
                        } else {
                            shippingFee += element.amount;
                        }
                    }
                    $scope.shipping_fee = parseFloat(shippingFee);
                    let otherFee = $scope.calculateOtherFee(paypalFee);
                    let otherTaxFee = 0;
                    if ($scope.validTax) {
                        otherTaxFee = $scope.calculateTrumpTax();
                    }
                    try {
                        const response = await $http({
                            method: 'POST',
                            url: base_api_url + '/paypal/express/update-shipping',
                            data: {
                                selected_shipping_option: $scope.selectedShippingCart,
                                shipping_info: $scope.shippingInfoResponse,
                                amount: $scope.cart.sub_total + otherFee + otherTaxFee,
                                order_id: data.orderID, 
                                shippingOptions, 
                                account: $scope.paypalAccount,
                                service_token: "megaads@123",
                                country: countryId,
                            }
                        });
                        const dataResponse = response.data;
    
                        if (dataResponse.status === 'successful') {
                            return actions.resolve();
                        }
                        throw new Error(dataResponse.message || 'Failed to update shipping.');
                    } catch (err) {
                        console.error('Update Shipping Error:', err);
                        return actions.reject('Failed to update shipping: ' + err.message);
                    }
                }
                return actions.resolve();
            },       
            onApprove: async function(data, actions) { 
                return actions.order.get().then(async function(orderData) {
                    let shippingData = orderData.purchase_units[0].shipping;
                    let shipping = {
                        country: shippingData.address.country_code,
                        postalCode: shippingData.address.postal_code,
                        city: shippingData.address.admin_area_2,
                        region: shippingData.address.admin_area_1,
                        addressLine: [
                            shippingData.address.address_line_1,
                            shippingData.address.address_line_2,
                        ]
                    }
                    let payer = orderData.payer;
                    let phone = "000000";
                    if (payer.phone && payer.phone.phone_number && payer.phone.phone_number.national_number) {
                        phone = payer.phone.phone_number.national_number;
                        if (payer.phone.phone_number.country_code) {
                            shipping.country = payer.phone.phone_number.country_code;
                        }
                    }
                    if (phone == "000000" && shippingData.phone_number && shippingData.phone_number.national_number) {
                        phone = shippingData.phone_number.national_number;
                        if (shippingData.phone_number.country_code) {
                            shipping.country = shippingData.phone_number.country_code;
                        }
                    }
                    let data = {
                        payerName: payer.name.given_name + ' ' + payer.name.surname,
                        payerEmail: payer.email_address,
                        payerPhone: phone,
                        shippingAddress: shipping,
                        shippingOptions: shippingData.options && shippingData.options.length > 0 ? shippingData.options : null,
                    }
                    let order = await processOrder(data, "PAYPAL");
                    await updateInvoice(order.code, orderData.id);
                    let locale = "";
                    if (typeof localePrefix !== 'undefined' && localePrefix !== '') {
                        locale = `/${localePrefix}`;
                    }
                    let host = window.location.origin + locale;
                    $http({
                        method: 'GET',
                        url: base_api_url + '/paypal/v2/confirm?customerToken=' + $scope.customer.token + '&order_code=' + order.code + '&token=' + orderData.id + '&ignore_localization=1&type_return=json&host=' + host,
                    }).then(response => {
                        window.location.href = response.data.result;
                    });
                }).catch(function(error) {
                    console.error("Error fetching order details:", error);
                });
            },
            onError: function(err) {
                alert('Error: ' + err.message);
            }
        }).render('#paypal-button-container');
    }

    $scope.getPaypalShippingOption = (shippingInfo, isUpdate = false) => {
        var shippingOptions = [];
        var shippingData = [];
        for (let index = 0; index < shippingInfo.length; index++) {
            const element = shippingInfo[index];
            element.shipping_info.forEach(item => {
                element[item.type] = item;
                if (!shippingData[item.type]) {
                    shippingData[item.type] = angular.copy(item);
                } else {
                    shippingData[item.type].shipping_fee += item.shipping_fee;
                }
            });
        }
        let types = ["standard", "premium", "express"];
        for (let index = 0; index < shippingInfo.length; index++) {
            for (let i = 0; i < types.length; i++) {
                const type = types[i];
                if (!shippingInfo[index][type]) {
                    delete(shippingData[type]);
                }
            }
        }
        if (isUpdate) {
            $scope.selectedShippingCart = [];
        }
        let hasStandard = false;
        let hasPremium = false;
        for (const key in shippingData) {
            if (shippingData.hasOwnProperty.call(shippingData, key)) {
                const element = shippingData[key];
                if (element.type == 'standard') {
                    hasStandard = true;
                }
                if (element.type == 'premium') {
                    hasPremium = true;
                }
            }
        }
        for (const key in shippingData) {
            if (shippingData.hasOwnProperty.call(shippingData, key)) {
                const element = shippingData[key];
                let minDate = new Date();
                let maxDate = new Date();
                minDate.setDate(minDate.getDate() + parseInt(element.shipping_min_time));
                maxDate.setDate(maxDate.getDate() + parseInt(element.shipping_max_time));
                let textTemplate = betweenFromToText;
                textTemplate = textTemplate.replace('#key', element.name_shipping);
                textTemplate = textTemplate.replace('#from', `${monthNamesHeader[minDate.getMonth()].replace("#date", minDate.getDate())}`);
                textTemplate = textTemplate.replace('#to', `${monthNamesHeader[maxDate.getMonth()].replace("#date", maxDate.getDate())}`);
                let dataOption = {
                    id: element.type,
                    label: element.name_shipping,
                    detail: textTemplate,
                    amount: element.shipping_fee,
                    selected: element.type == $scope.shippingTypeCart,
                };
                shippingOptions.push(dataOption);
                if (isUpdate && element.type == 'standard' && hasStandard) {
                    $scope.selectedShippingCart.push(dataOption);
                    $scope.shippingTypeCart = 'standard';
                }
                if (isUpdate && element.type == 'premium' && !hasStandard && hasPremium) {
                    $scope.selectedShippingCart.push(dataOption);
                    $scope.shippingTypeCart = 'premium';
                }
                if (isUpdate && element.type == 'express' && !hasPremium && !hasStandard) {
                    $scope.selectedShippingCart.push(dataOption);
                    $scope.shippingTypeCart = 'express';
                }
            }
        }
        return shippingOptions;
    }

    async function processOrder(data) {
        //Create order
        let tokenUserQuery = localStorage.getItem("token_user_query");
        //Build tracking source
        var buildTrackingReqParams = {
            url: '/tracking-order/build-tracking-source?token=' + tokenUserQuery,
            method: 'GET',
        };
        await $.ajax(buildTrackingReqParams).done(function(result) {
            console.log("Done tracking");
        });

        let token = $scope.customer.token;
        let shippingConfig = {};
        for (let index = 0; index < $scope.shippingInfoResponse.length; index++) {
            const element = $scope.shippingInfoResponse[index];
            element.shipping_info.forEach(item => {
                element[item.type] = item;
            });
        }
        if (data.shippingOptions && data.shippingOptions.length > 0) {
            for (let index = 0; index < data.shippingOptions.length; index++) {
                if (data.shippingOptions[index].selected) {
                    $scope.shippingTypeCart = data.shippingOptions[index].id;
                }
            }
        }
        for (let index = 0; index < $scope.items.length; index++) {
            const element = $scope.items[index];
            for (let i = 0; i < $scope.shippingInfoResponse.length; i++) {
                const item = $scope.shippingInfoResponse[i];
                let shippingInfo = item[$scope.shippingTypeCart];
                for (let k = 0; k < item.cart_item_id.length; k++) {
                    const cartItemId = item.cart_item_id[k];
                    shippingConfig[cartItemId] = shippingInfo.id
                }
            }
        }
        let shippingAddress = data.shippingAddress;
        var headers = {
            token: token,
        };
        let billingAddress = null;
        if (data.paymentMethod && data.paymentMethod.billing_details) {
            billingAddress = data.paymentMethod.billing_details;
        } else {
            billingAddress = {
                address: {
                    country: shippingAddress.country,
                    postal_code: shippingAddress.postalCode,
                    city: shippingAddress.city ? shippingAddress.city : '',
                    state: shippingAddress.region,
                    line1: shippingAddress.addressLine && shippingAddress.addressLine[0] ? shippingAddress.addressLine[0] : 'address 1',
                    line2: shippingAddress.addressLine && shippingAddress.addressLine[1] ? shippingAddress.addressLine[1] : '',
                }
            }
        }
        let countryId = 226;
        let countryBilling = 226;
        let hasBilling = false;

        for (const key in $scope.countries) {
            if (Object.hasOwnProperty.call($scope.countries, key)) {
                const element = $scope.countries[key];
                
                if (element.iso == shippingAddress.country) {
                    countryId = element.id;
                }
                if (billingAddress && billingAddress.address && billingAddress.address.country && element.iso == billingAddress.address.country) {
                    hasBilling = true;
                    countryBilling = element.id;
                }
            }
        }
        if (!hasBilling) {
            countryBilling = countryId;
        }
        let dataOrder = {
            name: data.payerName,
            zipcode: shippingAddress.postalCode ? shippingAddress.postalCode : 0,
            phone: data.payerPhone.replace(/\s/gm, ''),
            country: countryId,
            province: null,
            district: null,
            city_name: shippingAddress.city ? shippingAddress.city : "",
            state_name: shippingAddress.region,
            optional_address: shippingAddress.addressLine && shippingAddress.addressLine[1] ? shippingAddress.addressLine[1] : '',
            email: data.payerEmail.replace(/\s/gm, ''),
            note: null,
            address: shippingAddress.addressLine && shippingAddress.addressLine[0] ? shippingAddress.addressLine[0] : 'address 1',
            payment_type: 'paypal_express',
            promotion_code: null,
            delivery_note: "",
            shipping_type: $scope.shippingTypeCart,
            discount: 0,
            tips: 0,
            billing_address: JSON.stringify({
                name: billingAddress && billingAddress.name ? billingAddress.name : data.payerName,
                address: billingAddress.address.line1,
                optional_address: billingAddress.address.line2,
                state_name: billingAddress.address.state,
                zip_code: billingAddress.address.postal_code,
                city_name: billingAddress.address.city,
                country: countryBilling,
            }),
            shipping_configuration: JSON.stringify(shippingConfig),
            token: token,
            checkout_source: "cart",
            shipping_info: $scope.shippingInfoResponse,
        };

        if (tokenUserQuery) {
            dataOrder.token_user_query = tokenUserQuery;
        }
        if ($scope.validTax) {
            dataOrder.other_tax_fee = $scope.calculateTrumpTax();
        }
        dataOrder.cjeventCookie = cjeventCookie;
        let orderData = null;
        await order(dataOrder).then(function (result) {
            orderData = result.order;
        }).catch(function (err) {
            console.error('Augh, there was an error!', err.statusText);
        });
        return orderData;
    }

    $scope.calculateTrumpTax = (formatPrice = false) => {
        let shippingFee = 0;
        for (let index = 0; index < $scope.selectedShippingCart.length; index++) {
            const element = $scope.selectedShippingCart[index];
            if (element.amount && element.amount.value) {
                shippingFee += element.amount.value;
            } else {
                shippingFee += element.amount;
            }
        }
        let amount = 0;
        if ($scope.cart && $scope.cart.sub_total) {
            amount = $scope.cart.sub_total;
            amount += shippingFee;
        }
        if (amount < 0) {
            amount = 0;
        }
        let taxPercent = 20;
        let taxAmount = amount * taxPercent / 100;
        taxAmount = decimalAdjust('ceil', taxAmount);
        if (isNaN(taxAmount) || taxAmount < 0) {
            taxAmount = 0;
        }
        if (formatPrice) {
            return $scope.formatPrice(taxAmount, 0, false);
        } else {
            return taxAmount;
        }
    }

    $scope.checkTax = (countryId = null) => {
        return new Promise((resolve, reject) => {
            $scope.validTax = false;
            if (countryId && countryId == 226) {
                $http({
                    method: "GET",
                    url: '/cart/tax-us?country=' + countryId,
                }).then(async function successCallback(response) {
                    if (response.data.status == "successful") {
                        if (response.data.result) {
                            $scope.validTax = true;
                        }
                    }
                    resolve(true);
                }).catch(function errorCallback(error) {
                    reject(error);
                });
            } else {
                resolve(true);
            }
        });
    }

    async function updateInvoice(orderCode, orderId) {
        await $http({
            method: 'POST',
            url: base_api_url + '/paypal/express/update-invoice',
            data: {
                order_code: orderCode,
                order_id: orderId,
                account: $scope.paypalAccount,
                service_token: "megaads@123"
            }
        });
    }

    function order(dataOrder) {
        dataOrder.service_token = "megaads@123";
        return new Promise((resolve, reject) => {
            let orderData = {};
            const xhr = new XMLHttpRequest();
    
            xhr.open("POST", base_api_url_header + "/api/order");
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.setRequestHeader("Token", dataOrder.token);
            xhr.send(JSON.stringify(dataOrder));
            xhr.onreadystatechange = function () {
                if (this.readyState === 4 && this.status === 200) {
                    let responseText = this.responseText;
    
                    const orderData = JSON.parse(responseText);
                    resolve(orderData)
                }
            };
        })
    }

    $scope.getWishlistItems = () => {
        $http({
            method: "GET",
            url: "/get-wishlist-items",
        }).then(function(response) {
            $scope.wishlistItems = response.data.result;
            for (let index = 0; index < $scope.wishlistItems.length; index++) {
                const element = $scope.wishlistItems[index];
                for (let i = 0; i < $scope.items.length; i++) {
                    const item = $scope.items[i];
                    if (element.product_id == item.product_id && element.product_sku_id == item.product_sku_id && JSON.stringify(element.configurations) == JSON.stringify(item.configurations)) {
                        item.is_wishlist = true;
                    }
                }
            }
        });
    }

    $scope.addToWishlist = (item) => {
        $http({
            method: "POST",
            url: "/add-to-wishlist",
            data: {
                productId: item.product_id,
                productSkuId: item.product_sku_id,
                configurations: JSON.stringify(item.configurations)
            }
        }).then(function(response) {
            if (response.data.status == "successful") {
                $scope.getWishlistItems();
            }
        });
    }
    
    $scope.initial();
});
$(document).ready(function() {

    function copyToClipboard(code) {
        var $temp = $("<input>");
        $("body").append($temp);
        $temp.val(code).select();
        document.execCommand("copy");
        $temp.remove();
    }

    $(document).on('click', '.discount-icon', function () {
        var code = $(this).data("code");
        copyToClipboard(code);
        $(this).children().find('.copy-action').hide();
        $(this).children().find('.copy-done').show();
    })


    $(document).on('mouseleave', '.discount-icon', function () {
        setTimeout(function(){
            $('.copy-action').show();
            $('.copy-done').hide();
        }, 800);
    });
})
function decorePrice(price) {
    if (priceConfig) {
        price = (parseFloat(price) + parseFloat(priceConfig["adding_price"])) * parseFloat(priceConfig["ratio"]);
        price = decimalAdjust('ceil', price);
    }
    return price;
}

function decimalAdjust(type, value) {
    let matches = priceTemplate.match(/{money}{([^a-zA-z0-9]+)}{([0-9]+)}/);
    let exp = -2;
    if (matches.length == 3) {
        exp = parseInt(matches[2] * (matches[2] ? -1 : 1));
    }
    // If the exp is undefined or zero...
    if (typeof exp === 'undefined' || +exp === 0) {
        return Math[type](value);
    }
    value = +value;
    exp = +exp;
    // If the value is not a number or the exp is not an integer...
    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
        return NaN;
    }
    // Shift
    value = value.toString().split('e');
    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
    // Shift back
    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}

function getHighPriceHtml(item) {
    if (item.high_price && parseFloat(item.high_price) > parseFloat(item.price)) {
        return `<small style="text-decoration: line-through; color: #a1a1a1; padding-left: 5px;">${formatPrice(decorePrice(item.high_price), priceTemplate)}</small>`;
    }
    return '';
}

document.addEventListener("DOMContentLoaded", function(event) {
    $.ajax({url: "/cart/related-product"}).done(function(response) {
        if (typeof tenancyToken !== 'undefined' && tenancyToken != '') {
            return;
        }
        var locale = '';
        if (typeof localePrefix !== 'undefined' && localePrefix !== '') {
            locale = '/' + localePrefix;
        }
        if (response.status == 'successful') {
            const relatedProducts = response.result;
            if (relatedProducts && relatedProducts.length > 0) {

                let domHtmlElements = [];
                relatedProducts.forEach(element => {
                    let url = element.url;
                    if (locale != '' && !element.url.includes(locale + "/")) {
                        url = locale + element.url;
                    }
                    domHtmlElements.push(`
                        <div class="md-also-bought-item-wrapp swiper-slide">
                            <div class="md-also-bought-item">
                                <a class="md-also-bought-link" href="${url}?internal_source=cart-recommendation" target="_blank">
                                    <img class="md-also-bought-image" src="${getImageCdn(element.image_url, 540, 540)}" alt="${element.name}" referrerpolicy="no-referrer">
                                </a>
                                <div class="md-also-bought-title-box flex-b align-c">
                                    <a class="md-product-title" href="${url}?internal_source=cart-recommendation" target="_blank">
                                        ${element.name}
                                    </a>
                                </div>
                                <span class="md-also-bought-price">
                                    ${element.display_price}
                                    ${getHighPriceHtml(element)}
                                </span>
                            </div>
                        </div>
                    `);
                });

                let html = `
                    <div class="swiper-wrapper">
                        ${domHtmlElements.join('')}
                    </div>
                    <div class="swiper-button-next md-also-btn-next"></div>
                    <div class="swiper-button-prev md-also-btn-prev"></div>
                `
                $("#also-bought-content").find(".md-also-bought-list").html(html);
                $("#also-bought-content").show();

                if (!isMobile) {

                    var swiper = new Swiper('.md-also-bought-list', {
                        slidesPerView: 2.1,
                        slidesPerGroup: 2.1,
                        spaceBetween: 6,
                        navigation: {
                            nextEl: ".md-also-btn-next",
                            prevEl: ".md-also-btn-prev",
                        },
                        breakpoints: {
                            760: {
                                slidesPerView: 3,
                                slidesPerGroup: 3,
                            },
                            900: {
                                slidesPerView: 4,
                                slidesPerGroup: 4,
                            },
                            1000: {
                                slidesPerView: 5,
                                slidesPerGroup: 5,
                            },
                            1300: {
                                slidesPerView: 6,
                                slidesPerGroup: 6,
                            }

                        },
                    });
                }
            }
        }
    })
})