(function () {
    global.dashModule
        .controller('shopPackageDetailsCtrl', ['$scope', '$http', '$', '$translate', '$sce', 'utilsService', 'shopCartService', shopPackageDetailsController])
        .directive('shopPackageDetails', [shopPackageDetailsDirective]);

    function shopPackageDetailsDirective() {
        return {
            restrict: 'E',
            templateUrl: 'shop/html/shopPackageDetailsTemplate'
        };
    }

    function shopPackageDetailsController($scope, $http, $, $translate, $sce, utilsService, shopCartService) {
        $scope.onPriceSelect = onPriceSelect;
        $scope.getShopPackageDetails = getShopPackageDetails;
        $scope.addToCart = addToCart;
        $scope.sumPrices = sumPrices;
        $scope.showInfo = showInfo;
        $scope.getPriceClass = getPriceClass;
        $scope.getOptionClass = getOptionClass;
        $scope.getAdditionalClass = getAdditionalClass;
        $scope.selectOption = selectOption;
        $scope.getOptionPriceText = getOptionPriceText;
        $scope.getFixedPrice = getFixedPrice;
        $scope.getRecurrentPrice = getRecurrentPrice;
        $scope.selectAdditional = selectAdditional;
        $scope.hasOptions = hasOptions;
        $scope.renderHtml = renderHtml;
        $scope.showOptionInfo = showOptionInfo;
        $scope.selectedPackage = {};
        $scope.selectedOptions = {
            other: {}
        };
        $scope.idCommercialLead = 0;

        function renderHtml(htmlCode) {
            return $sce.trustAsHtml(htmlCode);
        }

        function getShopPackageDetails() {
            const idPackage = global.getParameterByName('idPackage') || 0;
            const idCommercialLead = global.getParameterByName('idCommercialLead') || 0;
            const params = $.param({
                idCommercialLead,
                idPackage
            });

            $http({
                method: 'POST',
                url: 'shop/api/getShopPackageDetails',
                data: params
            }).then(setShopPackageDetails, utilsService.onHttpError);
        }

        function setShopPackageDetails(response) {
            if (response.data && response.data.prices && response.data.packageInfo && response.data.commercialLead) {
                $scope.country = response.data.country;
                $scope.selectedPackage = response.data.packageInfo;
                $scope.selectedPackage.documents = response.data.documents;
                $scope.selectedPackage.prices = response.data.prices || [];
                $scope.selectedPackage.commercialLead = response.data.commercialLead || [];
                $scope.selectedPackage.groups = response.data.groups || [];
                $scope.selectedPackage.additionalPackages = response.data.additionalPackages || [];
                if ($scope.selectedPackage.prices[0]) {
                    $scope.selectedOptions.idPaymentType = $scope.selectedPackage.prices[0].idPaymentType;
                    $scope.selectedOptions.price = $scope.selectedPackage.prices[0];
                }
                $.each($scope.selectedPackage.groups, (key, group) => {
                    const defaultValue = group.options.find((value) => {
                        return parseInt(value.isDefault) === 1;
                    });
                    $scope.selectedOptions.other[group.idGroup] = defaultValue ? defaultValue.idOptionPackage : group.options[0].idOptionPackage;
                });

                $scope.selectedOptions.additionalPackages = {};
                updateAvailability();
            }
        }

        function hasOptions() {
            return Object.keys($scope.selectedPackage.groups).length > 0;
        }

        function getPriceClass(price) {
            return price === $scope.selectedOptions.price ? 'selected-price' : '';
        }

        function getOptionClass(key, value) {
            return value === $scope.selectedOptions.other[key] ? 'selected-option' : '';
        }

        function getAdditionalClass(key) {
            return $scope.selectedOptions.additionalPackages[key] ? 'selected-option' : '';
        }

        function updateAvailability() {
            $.each($scope.selectedPackage.groups, (key, group) => {
                group.options.forEach((value) => {
                    value.isAvailable = getSelectedPriceForOption(value) ? true : false;
                    value.isInfoBoxVisible = false;
                });
            });
            $scope.selectedPackage.additionalPackages.forEach((value) => {
                value.isAvailable = getSelectedPriceForOption(value) ? true : false;
                value.isInfoBoxVisible = false;
            });
        }

        function onPriceSelect(idPaymentType) {
            $scope.selectedOptions.idPaymentType = idPaymentType;
            $scope.selectedOptions.price = $scope.selectedPackage.prices.filter(value => {
                return value.idPaymentType === idPaymentType;
            })[0];
            updateAvailability();
        }

        function showUnavailableMessage(unavailablePackages) {
            let translatedMessage = $translate.instant('shop.messages.UNAVAILABLE_PACKAGES');
            unavailablePackages.forEach((unavailablePacakgeName) => {
                translatedMessage += ' ' + unavailablePacakgeName + ',';
            });
            translatedMessage = translatedMessage.slice(0, -1);
            utilsService.displayMessage('warning', translatedMessage);
        }

        function addToCart() {
            const unavailablePackages = [];
            const extraPackages = [];
            Object.keys($scope.selectedOptions.additionalPackages).forEach((idAdditionalPackage) => {
                if ($scope.selectedOptions.additionalPackages[idAdditionalPackage] === true) {
                    const extraPackage = $scope.selectedPackage.additionalPackages.find((additionalPackage) => {
                        return additionalPackage.idAdditionalPackage === idAdditionalPackage;
                    });

                    if (!extraPackage.isAvailable) {
                        unavailablePackages.push(extraPackage.packageName);
                    }
                    extraPackages.push(idAdditionalPackage);
                }
            });

            $.each($scope.selectedOptions.other, (key, idOptionValue) => {
                let extraPackage;
                $.each($scope.selectedPackage.groups, (key, group) => {
                    if(extraPackage){
                        return;
                    }
                    extraPackage = group.options.find((optionPackage) => {
                        return optionPackage.idOptionPackage === idOptionValue;
                    });

                });
                if (!extraPackage.isAvailable) {
                    unavailablePackages.push(extraPackage.optionName);
                }
                extraPackages.push(idOptionValue);
            });

            if (unavailablePackages.length) {
                showUnavailableMessage(unavailablePackages);
            } else {
                const params = $.param({
                    idPackage: $scope.selectedPackage.idPackage,
                    idPrice: $scope.selectedOptions.price.idPrice,
                    options: JSON.stringify(extraPackages)
                });

                $http({
                    method: 'POST',
                    url: 'shop/api/addToCart',
                    data: params
                }).then(updateMessage, utilsService.onHttpError);
            }
        }

        function updateMessage(response) {
            if (typeof response.data.messages !== 'undefined') {
                response.data.messages.forEach((messageObj) => {
                    const translatedMessage = $translate.instant('shop.messages.' + messageObj.message);
                    utilsService.displayMessage(messageObj.code, translatedMessage);
                    if (messageObj.message === 'PACKAGE_ADDED') {
                        shopCartService.updateShopCartCount();
                    }
                });
            }
        }

        function sumPrices(values) {
            let total = 0;
            values.forEach((val) => {
                total += parseFloat(val);
            });

            return total;
        }

        function showInfo(price) {
            price.isInfoVisible = !price.isInfoVisible;
        }

        function selectOption(key, value) {
            $scope.selectedOptions.other[key] = value;
        }

        function selectAdditional(key) {
            $scope.selectedOptions.additionalPackages[key] = !$scope.selectedOptions.additionalPackages[key];
        }

        function getSelectedPriceForOption(optionPackage) {
            return optionPackage.prices.find((price) => {
                return price.idPaymentType === $scope.selectedOptions.idPaymentType;
            });
        }

        function getOptionPriceText(name, optionPackage) {
            let optionPriceText = name + ' ';
            const selectedPrice = getSelectedPriceForOption(optionPackage);

            if (!selectedPrice) {
                optionPriceText += '<span class="not-available">(' + $translate.instant('shop.extra.NOT_AVAILABLE') + ')</span>';

                return $sce.trustAsHtml(optionPriceText);
            }

            const fixedPrice = selectedPrice.fixedExtra + ' ' + $scope.country.currency;
            const recurentPrice = sumPrices([selectedPrice.recurentExtra, selectedPrice.servicesExtra]) + ' ' + $scope.country.currency;

            if (parseFloat(fixedPrice) === 0 && parseFloat(recurentPrice) === 0) {
                optionPriceText += '(' + $translate.instant('shop.extra.NO_COST') + ')';

                return $sce.trustAsHtml(optionPriceText);
            }

            optionPriceText += parseFloat(recurentPrice) === 0 ? fixedPrice : fixedPrice + ' + (' + recurentPrice + ' / ' + selectedPrice.periodUnit + ' )';

            return $sce.trustAsHtml(optionPriceText);
        }

        function getFixedPrice() {
            let totalPrice = $scope.selectedOptions.price.fixedExtra;
            $.each($scope.selectedOptions.other, (idGroup, idOptionPackage) => {
                const selectedOption = $scope.selectedPackage.groups[idGroup].options.find((option) => {
                    return option.idOptionPackage === idOptionPackage;
                });
                const selectedPrice = selectedOption.prices.find((price) => {
                    return price.idPaymentType === $scope.selectedOptions.idPaymentType;
                });
                if (selectedPrice && selectedPrice.fixedExtra) {
                    totalPrice = sumPrices([totalPrice, selectedPrice.fixedExtra]);
                }
            });

            $.each($scope.selectedOptions.additionalPackages, (idAdditionalPackage, value) => {
                if (value === true) {
                    const selectedAdditional = $scope.selectedPackage.additionalPackages.find((option) => {
                        return option.idAdditionalPackage === idAdditionalPackage;
                    });
                    const selectedPrice = selectedAdditional.prices.find((price) => {
                        return price.idPaymentType === $scope.selectedOptions.idPaymentType;
                    });
                    if (selectedPrice && selectedPrice.fixedExtra) {
                        totalPrice = sumPrices([totalPrice, selectedPrice.fixedExtra]);
                    }
                }
            });

            return totalPrice;
        }

        function getRecurrentPrice() {
            let totalPrice = sumPrices([$scope.selectedOptions.price.recurentExtra, $scope.selectedOptions.price.servicesExtra]);
            $.each($scope.selectedOptions.other, (idGroup, idOptionPackage) => {
                const selectedOption = $scope.selectedPackage.groups[idGroup].options.find((option) => {
                    return option.idOptionPackage === idOptionPackage;
                });
                const selectedPrice = selectedOption.prices.find((price) => {
                    return price.idPaymentType === $scope.selectedOptions.idPaymentType;
                });
                if (selectedPrice && selectedPrice.recurentExtra && selectedPrice.servicesExtra) {
                    totalPrice = sumPrices([totalPrice, selectedPrice.recurentExtra, selectedPrice.servicesExtra]);
                }
            });

            $.each($scope.selectedOptions.additionalPackages, (idAdditionalPackage, value) => {
                if (value === true) {
                    const selectedAdditional = $scope.selectedPackage.additionalPackages.find((option) => {
                        return option.idAdditionalPackage === idAdditionalPackage;
                    });
                    const selectedPrice = selectedAdditional.prices.find((price) => {
                        return price.idPaymentType === $scope.selectedOptions.idPaymentType;
                    });
                    if (selectedPrice && selectedPrice.recurentExtra && selectedPrice.servicesExtra) {
                        totalPrice = sumPrices([totalPrice, selectedPrice.recurentExtra, selectedPrice.servicesExtra]);
                    }
                }
            });

            return totalPrice;
        }

        function showOptionInfo(optionPacakge) {
            optionPacakge.isInfoBoxVisible = !optionPacakge.isInfoBoxVisible;
        }
    }
})();
