makeChangeApp.requires.push('sku-chosen');
makeChangeApp.requires.push('print-location-selector');

makeChangeApp.controller("MakeChangeController", function ($scope, $http, $timeout) {
    $scope.printLocations = printLocations;
    $scope.printLocationsPrice = printLocationsPrice;
    $scope.addedToCartText = addedToCartText;
    $scope.originOrder = typeof originOrder !== 'undefined' ? originOrder : null;
    $scope.additionalPriceConfig = {};
    $scope.baseAdditionalPrice = 0;

    $scope.openFormChangeVariant = async (item) => {
        item.loadingMakeChange = true;
        $scope.currentCartItem = item;
        $scope.newItem = {
            quantity: item.quantity,
        };
        $scope.currentProduct = {};
        $scope.currentVariant = {
            ...item,
            status: 'ACTIVE',
            id: item.product_sku_id
        };
        $scope.variantOptionSelected = {};
        $scope.variantImageSelected = {};
        $scope.bulkPriceBySku = {};
        $scope.variants = {};
        $scope.products = {};
        $scope.variantBases = {};
        $scope.groupVariants = [];
        $scope.variantsStatistic = [];
        $scope.additionalPriceConfig = {};
        await $scope.getProduct(item);
        await $scope.getBulkPrices(item.product_id);
        $scope.buildPricePrintLocation($scope.currentProduct);
        $('.checkout-popup-wrapper').addClass("show-modal-edit");
        $('body').addClass('open-update-item-popup');
        $timeout(function() {
            const activeVariant = document.querySelector('.choose-image-variant.active');
            if (activeVariant) {
                activeVariant.scrollIntoView({
                    behavior: 'smooth',
                    block: 'nearest',
                    inline: 'center'
                });
            }
        });
        window.dispatchEvent(new CustomEvent('makeChangeProductDone', {detail: item}));
    }

    $scope.getProduct = (item) => {
        return new Promise(function (resolve) {
            $http({
                method: "GET",
                url: '/product/find?id=' + item.product_id,
            }).then(function successCallback(response) {
                if (response.data.status == "successful") {
                    $scope.currentProduct = response.data.result;
                    if (item.configurations && item.configurations.print_location) {
                        $scope.currentProduct.print_location = item.configurations.print_location;
                        $scope.currentProduct.tmp_print_location = item.configurations.print_location;
                    }
                    if ($scope.currentProduct.variant_default && $scope.currentProduct.variant_default.id) {
                        $scope.currentProduct.product_sku_id = $scope.currentProduct.variant_default.id;
                        $scope.currentProduct.price = parseFloat($scope.currentProduct.variant_default.price);
                        $scope.currentProduct.high_price = parseFloat($scope.currentProduct.variant_default.high_price);
                        if ($scope.currentProduct.variant_default.image_url) {
                            $scope.currentProduct.image_url = $scope.currentProduct.variant_default.image_url;
                        }
                    }
                    if ($scope.currentProduct.attributes.print_locations && $scope.currentProduct.attributes.print_locations.length > 0) {
                        $scope.currentProduct.attributes.print_locations.forEach(item => {
                            const matchingPrintLocation = $scope.printLocations.find(location => location.value === item.value);
                            if (matchingPrintLocation) {
                                item.selectImage = matchingPrintLocation.selectImage;
                                item.defaultImage = matchingPrintLocation.defaultImage;
                            } else {
                                // Optional: Set to default or null if no match is found
                                item.selectImage = null;
                                item.defaultImage = null;
                            }
                        });
                    } else {
                        $scope.currentProduct.attributes.print_locations = $scope.printLocations;
                    }
                    resolve();
                }
            }).catch(function errorCallback(err) {
                console.log(err);
                resolve();
            });
        });
    }

    $scope.addItemToCart = async (type = 'add') => {
        $scope.loading = true;
        $scope.loadingRemoveItem = true;
        if ($scope.newItem.quantity <= 0) {
            toastr.error($scope.invalidQuantityText);
            $scope.loadingRemoveItem = false;
            $scope.loading = false;
            return;
        }
        if (type == 'update') {
            var rmReqParams = {
                url: '/cart/remove-cart-item',
                method: 'DELETE',
                data: {
                    ids: $scope.currentCartItem.id,
                    "_token": "{{ csrf_token() }}",
                }
            };
            await $http.delete("/cart/remove-cart-item?ids=" + $scope.currentCartItem.id).then(function(result) {
                if (result.status == 'successful') {
                    window.dispatchEvent(new CustomEvent('change-cart', {detail: {showCart: false}}));
                }
            });
        }
        let productSku = null;
        if ($scope.currentVariant) {
            productSku = $scope.currentVariant.id;
        }
        let productVariantOptions = [];
        if ($scope.currentVariant && $scope.currentVariant.variants) {
            for (let option of $scope.currentVariant.variants) {
                productVariantOptions.push(option.name);
            }
        }
        let configurations = null;
        if ($scope.currentCartItem.configurationsValue && $scope.currentCartItem.configurationsValue.length > 0) {
            try {
                configurations = JSON.parse($scope.currentCartItem.configurationsValue);
            } catch (error) {
                configurations = {};
                console.log(error);
            }
            if ($scope.currentProduct.is_custom == 0) {
                if ($scope.currentProduct.tmp_print_location) {
                    configurations.print_location = $scope.currentProduct.tmp_print_location;
                }
                configurations = JSON.stringify(configurations);
            } else {
                configurations = JSON.parse($scope.currentCartItem.configurationsValue);
                if ($scope.currentProduct.tmp_print_location) {
                    configurations.print_location = $scope.currentProduct.tmp_print_location;
                }
                configurations = JSON.stringify(configurations);
            }
        }
        let cartData = {
            productId: $scope.currentVariant.product_id,
            productSkuId: productSku,
            quantity: $scope.newItem.quantity,
            configurations: configurations,
            productVariantOptions: productVariantOptions.length ? productVariantOptions.join(', ') : ''
        };
        let url = '/cart/add-to-cart';
        if (typeof exchangeFingerprint !== "undefined" && exchangeFingerprint != "" && $scope.originOrder) {
            url += `?token=${exchangeFingerprint}_${$scope.originOrder.id}`;
        }
        var addCartReqParams = {
            url: url,
            method: 'POST',
            data: cartData
        };
        $http(addCartReqParams).then(async (response) => {
            if (response.data.status == "successful") {
                var addItem = {};
                response.data.cartItems.forEach((element) => {
                    if (element.product_id == cartData.productId && element.product_sku_id == cartData.productSkuId) {
                        addItem = element;
                    }
                })
                $scope.showMiniCart(addItem);
                window.dispatchEvent(new CustomEvent('change-cart', {detail: {showCart: false}}));
                $('.checkout-popup-wrapper').removeClass("show-modal-edit");
                $('body').removeClass('open-update-item-popup');
            }
            $scope.$applyAsync(function () {
                $scope.loading = false;
                $scope.loadingRemoveItem = false;
            })
        })
    }

    $scope.showMiniCart = (addItem) => {
        var locale = '';
        if (typeof localePrefix !== 'undefined' && localePrefix !== '') {
            locale = '/' + localePrefix;
        }
        if (addItem) {
            let miniCartHtml = "";
            let image = addItem.image_url;
            if (!image) {
                image = appUrl + "/images/official.png";
            }
            miniCartHtml += `
                <div class="mini-shopping-cart-image-box">
                    <span class="mini-shopping-cart-check">
                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check" viewBox="0 0 16 16">
                            <path d="M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z" />
                        </svg>
                    </span>
                    <img class="mini-shopping-cart-image" src="${getImageCdn(image, 630, 630)}" referrerpolicy="no-referrer"/>
                </div>
                <div class="mini-shopping-cart-title flex-b column" style="width: 68%;">
                    <div>${$scope.addedToCartText}</div>
                    <span class="js-shopping-cart-title">${addItem.product_name}</span>
                </div>
            `;
            $(".mini-shopping-wrapper").toggleClass("active");
            $("#mini-shopping-cart").html(miniCartHtml);
            setTimeout(() => {
                $(".mini-shopping-wrapper").toggleClass("active");
            }, 5000);
        }
    }

    $scope.removeCartItems = (item) => {
        if (confirm($scope.confirmRemoveItemText)) {
            $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.$applyAsync(function () {
                    $scope.loading = false;
                    $scope.loadingRemoveItem = false;
                })
            })
        }
    }

    $scope.classImage = (variant, type = "ELSE") => {
        let result = "";
        if (type == 'IMAGE') {
            result = "checkout-popup-choose-image-variant variant-image-item";
        } else if (type != 'IMAGE' && type != 'OPTION') {
            result = "checkout-popup-radio-label";
        }
        if ($scope.currentVariant && $scope.currentVariant.variants) {
            let isExists = $scope.currentVariant.variants.find(i => i.id == variant.id);
            if (isExists && isExists.id) {
                result += " active";
            }
        }
        return result;
    }

    $scope.getOptionIds = function (optionIds, valueWantToChange, result = []) {
        result.push(valueWantToChange.id);
        if (valueWantToChange.options && valueWantToChange.options.length) {
            let option = valueWantToChange.options[0];
            let values = []
            for (let item of $scope.variants) {
                if (item.id == option.variant_id) {
                    values = item.values;
                    break;
                }
            }
            let availableOptionIds = valueWantToChange.options.map(value => value.id);
            for (let item of values) {
                if (availableOptionIds.includes(item.id)) {
                    option = item;
                    break;
                }
            }

            for (let item of valueWantToChange.options) {
                if (optionIds.includes(item.id + '')) {
                    option = item;
                    break;
                }
            }
            result = $scope.getOptionIds(optionIds, option, result);
        }

        return result;
    }

    $scope.isSelected = (variant, type = "ELSE") => {
        let result = false;
        if ($scope.currentVariant && $scope.currentVariant.variants) {
            let isExists = $scope.currentVariant.variants.find(id => id == variant.id);
            if (isExists) {
                result = true;
            }
        }
        return result;
    }

    $scope.getPriceVariant = (option, groupId) => {
        let result = "";
        if ($scope.variants.length > 0) {
            let isStyleFirstVariant = $scope.variants[0].slug == 'style';
            let listIndex = [];
            let variantKeyMap = new Map();
            $scope.currentVariant.variants.forEach(optionId => {
                if ($scope.variantByOption[optionId] != groupId) {
                    variantKeyMap.set($scope.variantByOption[optionId], optionId);
                    listIndex.push(optionId);
                } else {
                    variantKeyMap.set($scope.variantByOption[option.id], option.id);
                }
            });
            let currentProductBySpid = $scope.products.productById[$scope.currentVariant.id];
            let key = [...variantKeyMap.values()].join('-');
            if (key in $scope.products.productByUniqId) {
                let price = $scope.products.productByUniqId[key].price;
                result = " (" + $scope.formatPriceMakeChange(price) + ")";
            } else {
                let prefixVariant = '';
                let variantIsOk = true;
                if (listIndex && listIndex.length >= 2) {
                    prefixVariant = listIndex[0] + '-' + option.id;
                    variantIsOk = false;
                    if ($scope.selectedSize || ($scope.currentVariant && $scope.currentVariant.id)) {
                        let keyWithColor = currentProductBySpid.variants.filter(id => $scope.variantByOption[id] != 2).map(id => $scope.variantByOption[id] == $scope.variantByOption[option.id] ? option.id : id).join('-');
                        if ($scope.variantsStatistic[keyWithColor]) {
                            variantIsOk = true;
                            prefixVariant = keyWithColor;
                        }
                    }
                    if (prefixVariant && $scope.variantsStatistic) {
                        if ($scope.variantsStatistic[prefixVariant]) {
                            variantIsOk = true;
                        } else if ($scope.variantsStatistic[option.id + '-' + listIndex[0]]) {
                            variantIsOk = true;
                            prefixVariant = option.id + '-' + listIndex[0];
                        }

                        if (!variantIsOk && isStyleFirstVariant && $scope.variantsStatistic[option.id]) {
                            prefixVariant = option.id;
                            variantIsOk = true;
                        }
                    }
                }
                if (variantIsOk && key && prefixVariant && $scope.variantsStatistic && $scope.variantsStatistic[prefixVariant]) {
                    result = "(" + $scope.formatPrice($scope.variantsStatistic[prefixVariant].price) + ")";
                }
            }
        }
        return result;
    }

    $scope.isFullImage = (item) => {
        let result = true;
        for (let index = 0; index < item.values.length; index++) {
            const element = item.values[index];
            if (!element.image_url) {
                result = false;
            }
        }
        return result;
    }

    $scope.getItemName = (item) => {
        let name = "";
        if (item.currentVariant && item.currentVariant.id) {
            item.currentVariant.variants.forEach((element, index) => {
                if ($scope.variantBases && $scope.variantBases.variantOptionById && $scope.variantBases.variantOptionById[element]) {
                    name += $scope.variantBases.variantOptionById[element];
                    if (index < item.currentVariant.variants.length - 1) {
                        name += ", ";
                    }
                }
            });
        }
        return name;
    }

    $scope.getCurrentVariantTotalAmount = (currentProduct) => {
        if (!currentProduct || !currentProduct.price) return;
        let price = parseFloat(currentProduct.price);
        price = $scope.getPrice(price);
        let amount = price * $scope.newItem.quantity;
        if (priceConfig) {
            amount = 0;
            let priceItem = parseFloat(price);
            priceItem += parseFloat(priceConfig.adding_price);
            priceItem *= parseFloat(priceConfig.ratio);
            amount = $scope.newItem.quantity * decimalAdjust('ceil', priceItem);
        }
        return amount;
    }


    $scope.getBulkPrices = (productId) => {
        let url = `${base_api_url}/product/bulk-price?product_id=${productId}`;
        $scope.bulkPriceBySku = {};
        return $http.get(url)
            .then(res => {
                try {
                    if (res.data.status == 'successful') {
                        $scope.bulkPriceBySku = res.data.result;
                    }
                } catch (error) {
                }
            }, err => {
                console.log('err', err);
            })
    }

    $scope.buildVariantsStatistic = () => {
        $scope.variantsStatistic = {}
        if ($scope.variants.length < 2) {
            return;
        }
        let firstOptionIndex = 0;
        for (let key in $scope.variants) {
            if ($scope.variants[key].type == 'OPTION') {
                firstOptionIndex = parseInt(key);
                break;
            }
        }
        for (let item of $scope.productVariants) {
            let vKeyArr = item.variants.filter((value, index) => index <= firstOptionIndex).map(item => item);
            for (let i = firstOptionIndex + 1; i < item.variants.length; i++) {
                let vKey = vKeyArr.join('-') + '-' + item.variants[i];
                if (!$scope.variantsStatistic[vKey]) {
                    $scope.variantsStatistic[vKey] = {
                        sku_key: item.variants.join('-'),
                        count: 1,
                        price: item.price,
                        high_price: item.high_price
                    }
                } else {
                    $scope.variantsStatistic[vKey].count++;
                    if (item.price < $scope.variantsStatistic[vKey]) {
                        $scope.variantsStatistic[vKey].sku_key = item.variants.join('-');
                        $scope.variantsStatistic[vKey].price = item.price;
                        $scope.variantsStatistic[vKey].high_price = item.high_price;
                    }
                }
            }

            let vKey = vKeyArr.join('-');

            if (!$scope.variantsStatistic[vKey]) {
                $scope.variantsStatistic[vKey] = {
                    sku_key: item.variants.join('-'),
                    count: 1,
                    price: item.price,
                    high_price: item.high_price
                }
            } else {
                $scope.variantsStatistic[vKey].count++;
                if (item.price < $scope.variantsStatistic[vKey]) {
                    $scope.variantsStatistic[vKey].sku_key = item.variants.join('-');
                    $scope.variantsStatistic[vKey].price = item.price;
                    $scope.variantsStatistic[vKey].high_price = item.high_price;
                }
            }
        }
    }

    window.addEventListener('makeChangeProduct', function (event, data) {
        let item = angular.copy(event.detail);
        $scope.openFormChangeVariant(item);
    });

    $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) {
            $scope.additionalPriceConfig.position = retVal;
        } else {
            delete $scope.additionalPriceConfig.position;
        }
        $scope.buildBulkOrder();
    }

    $scope.buildBulkOrder = () => {
        if ($scope.currentCartItem.configurationsValue) {
            if ($scope.bulkPriceBySku && $scope.bulkPriceBySku[$scope.currentVariant.id]) {
                let parseConfig = JSON.parse($scope.currentCartItem.configurationsValue);
                let bulkPrice = $scope.calculateBulkPrice($scope.currentVariant.id, $scope.newItem.quantity);
                if (bulkPrice) {
                    $scope.additionalPriceConfig["buy_more"] = {
                        type: "replace",
                        value: bulkPrice
                    }
                    parseConfig.price_by_quantity = {
                        price: bulkPrice
                    }
                    $scope.currentCartItem.configurationsValue = JSON.stringify(parseConfig);
                } else if ($scope.additionalPriceConfig["buy_more"]) {
                    delete $scope.additionalPriceConfig["buy_more"];
                }
            } else {
                if ($scope.additionalPriceConfig["buy_more"]) {
                    delete $scope.additionalPriceConfig["buy_more"];
                }
            }
        }
    } 
    
    $scope.calculateBulkPrice = function (spid, quantity) {
        let price = 0;
        let minQuantity = 0;
        for (let key of Object.keys($scope.bulkPriceBySku[spid])) {
            key = parseInt(key);
            if (key <= quantity) {
                price = $scope.bulkPriceBySku[spid][key];
            }
        }

        if (price) {
            return price;
        }
    }

    $scope.buildPricePrintLocation = (item) => {
        if (item.print_location) {
            $scope.buildAddPrice(parseFloat(item.price), item.tmp_print_location, item.category_ids);
        } else {
            $scope.buildBulkOrder();
        }
        item.show_high_price = item.high_price
        item.show_price = $scope.getPrice(parseFloat(item.price));
    }

    $scope.getReplacePrice = function () {
        for (let key of Object.keys($scope.additionalPriceConfig)) {
            let item = $scope.additionalPriceConfig[key];
            if (item.type == 'replace') {
                return item.value;
            }
        }

        return;
    }

    $scope.getPrice = function (price) {
        let replacePrice  = $scope.getReplacePrice();
        if (replacePrice) {
            price = replacePrice;
        }
        let additionalPrice = $scope.baseAdditionalPrice;
        if ($scope.additionalPriceConfig) {
            for (let key of Object.keys($scope.additionalPriceConfig)) {
                let item = $scope.additionalPriceConfig[key];
                switch (item.type) {
                    case 'percent':
                        additionalPrice += parseFloat(item.value) * parseFloat(price);
                        break;
                    case 'plus':
                        additionalPrice += parseFloat(item.value);
                        break;
                    default:
                        break;
                }
            }
        }
        price = parseFloat(price) + (!isNaN(additionalPrice) ? parseFloat(additionalPrice) : 0);
        price = parseFloat(price).toFixed(5);
        price = decimalAdjust('ceil', price);
        return price;
    }

    $scope.changeQuantity = () => {
        $scope.buildPricePrintLocation($scope.currentProduct);
    }

    $scope.changeQuantityByButton = (quantity) => {
        $scope.newItem.quantity = quantity;
        $scope.changeQuantity();
    }

    $scope.formatPriceMakeChange = function(price, numberAdd = 1, format = true) {
        price = $scope.getPrice(price);
        if (format) {
            if (globalPriceConfig) {
                price = (parseFloat(price) + parseFloat(globalPriceConfig.adding_price) * numberAdd) * parseFloat(globalPriceConfig.ratio);
            }
            price = parseFloat(price).toFixed(5);
            price = decimalAdjust('ceil', price);
        }
        return formatPrice(price, priceTempate);
    };

    $scope.onChangeSku = function (value) {
        $scope.currentVariant = {...value};
        $scope.currentProduct.image_url = value.gallery[0];
        $scope.currentProduct.price = value.price;
        $scope.currentProduct.high_price = value.high_price;
        $scope.buildPricePrintLocation($scope.currentProduct);
    }

    $scope.onChangePrintLocation = function (value) {
        if ($scope.currentVariant) {
            $scope.currentVariant.printLocationData = value;
        }
        $scope.currentProduct.tmp_print_location = value.position.value;
        $scope.buildPricePrintLocation($scope.currentProduct);
    }
});

$(document).ready(function () {
    $(document).on('keyup', function(e) {
        if (e.key == "Escape") {
            $('.checkout-popup-wrapper').removeClass("show-modal-edit");
            $('body').removeClass('open-update-item-popup');
        }
    });

    $(document).on('click','.checkout-popup-background, #js-checkout-cancel, .close-update-item, .close-body-open-button',function() {
        $('.checkout-popup-wrapper').removeClass("show-modal-edit");
        $('body').removeClass('open-update-item-popup')
    });
});