(function () {
    global.dashModule
        .controller('setPackagePriceCtrl', ['$scope', '$http', '$', '$translate', '$sce', 'finanncingService', 'utilsService', setPackagePriceCtrl])
        .directive('setPackagePrice', [setPackagePrice]);

    function setPackagePrice() {
        return {
            restrict: 'E',
            templateUrl: 'packages/html/setPackagePrice'
        };
    }

    function setPackagePriceCtrl($scope, $http, $, $translate, $sce, finanncingService, utilsService) {
        $scope.startSetPackagesPrices = startSetPackagesPrices;
        $scope.updateCommission = updateCommission;
        $scope.updateBrokerPricesAndCommission = updateBrokerPricesAndCommission;
        $scope.calculateTotalPrice = calculateTotalPrice;
        $scope.isPriceRecurring = isPriceRecurring;
        $scope.boundMessage = boundMessage;
        $scope.addPayType = addPayType;
        $scope.selectPayTypes = selectPayTypes;
        $scope.removePayType = removePayType;
        $scope.maxMarginExceded = maxMarginExceded;
        $scope.renderHtml = renderHtml;
        $scope.payTypesVisible = false;
        $scope.interestRate = 0;
        $scope.prices = [];
        $scope.selectedPrices = [];
        $scope.productsPrices = [];
        $scope.commissionSplit = {};
        $scope.packageProducts = [];
        $scope.calculateFinancing = finanncingService.calculateFinancing;
        $scope.setRecurrentPrice = setRecurrentPrice;
        $scope.calculateTotalCost = calculateTotalCost;

        function startSetPackagesPrices() {
            getPackageInfo();
            getPriceTypes();
        }

        function getPackageInfo() {
            const params = $.param({
                idPackage: global.getParameterByName('idPackage') || 0
            });

            $http({
                method: 'POST',
                url: 'packages/api/getPackageInfo',
                data: params
            }).then(showPackageInfo, utilsService.onHttpError);
        }

        function showPackageInfo(response) {
            if (response.data.info && response.data.products) {
                $scope.packageInfo = response.data.info[0];
                $scope.packageProducts = response.data.products;
            }
        }

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

        function getPriceTypes() {
            const params = $.param({
                idPackage: global.getParameterByName('idPackage') || 0
            });

            $http({
                method: 'POST',
                url: 'packages/api/getPriceTypes',
                data: params
            }).then(showPriceTypes, utilsService.onHttpError);
        }

        function showPriceTypes(response) {
            if (typeof response.data.priceTypes !== 'undefined' && typeof response.data.productsPrices !== 'undefined') {
                const prodPrices = response.data.productsPrices;
                const commissionSplit = response.data.commissionSplit ? response.data.commissionSplit : null;
                $scope.totalPrices = {};
                $scope.totalPrice = 0;

                $.each(prodPrices, (key, price) => {
                    if(key === 'service') {
                        if(!(key in $scope.totalPrices)) {
                            $scope.totalPrices[key] = {};
                        }
                        $scope.totalPrices[key]['recurringPrice'] = price.recurringPrice;
                        $scope.totalPrices[key]['fixedPrice'] = price.fixedPrice;
                    } else {
                        $scope.totalPrices[key] = price.totalUnitCost;
                        $scope.totalPrice += price.totalUnitCost;
                    }
                });

                $scope.productsPrices = prodPrices;
                $scope.selectedPrices = [];

                response.data.priceTypes.forEach(price => {
                    price.minimalFixedPrice = price.minimalFixedPrice ? parseFloat(price.minimalFixedPrice) : 0;
                    price.principalAmount = price.principalAmount ? parseFloat(price.principalAmount) : 0;
                    price.minimalServicesPrice = price.minimalServicesPrice ? parseFloat(price.minimalServicesPrice) : 0;

                    price.packagePayPeriod > 0 ? setRecurrentPrice(response.data.interestRate / 100, price) : price.minimalRecurentPrice = 0;

                    if (price.minimalFixedPrice || price.minimalRecurentPrice || price.minimalServicesPrice) {
                        price.isChecked = true;
                        $scope.selectedPrices.push(price);
                    } else {
                        price.isChecked = false;
                    }
                });

                $scope.prices = response.data.priceTypes;
                $scope.payTypesVisible = $scope.selectedPrices.length === 0;

                $scope.commissionSplit.broker = commissionSplit ? parseFloat(commissionSplit.broker) : 50;
                $scope.commissionSplit.commercialLead = commissionSplit ? parseFloat(commissionSplit.commercialLead) : 50;
                $scope.commissionSplit.payMargin = commissionSplit ? parseFloat(commissionSplit.payMargin) : 0;

                $scope.interestRate = response.data.interestRate;
            }
        }

        function updateCommission(userType) {
            if (userType === 'broker') {
                $scope.commissionSplit.commercialLead = 100 - $scope.commissionSplit.broker;
            } else {
                $scope.commissionSplit.broker = 100 - $scope.commissionSplit.commercialLead;
            }
        }

        function updateBrokerPricesAndCommission() {
            const params = $.param({
                idPackage: global.getParameterByName('idPackage') || 0,
                prices: JSON.stringify($scope.selectedPrices),
                commissionSplit: JSON.stringify($scope.commissionSplit)
            });

            $http({
                method: 'POST',
                url: 'packages/api/updateBrokerPricesAndCommission',
                data: params
            }).then(showUpdateMessage, utilsService.onHttpError);
        }

        function showUpdateMessage(response) {
            if (typeof response.data.messages !== 'undefined') {
                response.data.messages.forEach((messageObj) => {
                    const key = messageObj.key ? $translate.instant('packages.tables.headers.' + messageObj.key) : '';
                    let translatedMessage = $translate.instant('packages.messages.' + messageObj.message);
                    translatedMessage = key !== '' ? key + ': ' + translatedMessage : translatedMessage;
                    utilsService.displayMessage(messageObj.code, translatedMessage);
                    if (messageObj.code === 'success') {
                        getPriceTypes();
                    }
                });
            }
        }

        function calculateTotalPrice(unitCost, payPeriod, isPriceRecurring, quantity = 1) {
            const totalCost = isPriceRecurring === '1' ? unitCost * payPeriod * quantity : unitCost * quantity;

            return totalCost.toFixed(2);
        }

        function isPriceRecurring(recurring) {
            return parseInt(recurring) === 1;
        }

        function boundMessage(packagePayPeriod, periodUnit, type) {
            return (type === 'servicesContractPeriod' && parseInt(packagePayPeriod) === 0) ?
                'Unbound' :
                packagePayPeriod + ' ' + periodUnit;
        }

        function addPayType() {
            $scope.payTypesVisible = true;
        }

        function selectPayTypes() {
            $scope.prices.forEach((price) => {
                const indexOfElement = $scope.selectedPrices.indexOf(price);
                if (price.isChecked && indexOfElement === -1) {
                    $scope.selectedPrices.push(price);
                }

                if (!price.isChecked && indexOfElement !== -1) {
                    $scope.selectedPrices.splice(indexOfElement, 1);
                }
            });
            $scope.selectedPrices.sort((a, b) => {
                return a.idPayType > b.idPayType;
            });

            if ($scope.selectedPrices.length === 0) {
                const translatedMessage = $translate.instant('packages.messages.NO_PRICE_TYPE_SELECTED');
                utilsService.displayMessage('warning', translatedMessage);
            } else {
                $scope.payTypesVisible = false;
            }

        }

        function removePayType(key) {
            $scope.selectedPrices[key].isChecked = false;
            $scope.selectedPrices.splice(key, 1);
            $scope.payTypesVisible = $scope.selectedPrices.length === 0;
        }

        function maxMarginExceded(margin, totalCost) {
            return margin !== 0 && totalCost > margin;
        }


        function setRecurrentPrice(interestRate, price){
            price.minimalRecurentPrice = parseFloat(finanncingService.calculateFinancing(interestRate, price.packagePayPeriod, price.principalAmount));
        }

        function calculateTotalCost(totalPrices, type) {
            if(totalPrices) {
                let totalPrice = 0;
                if(type === 'fixed') {
                    if(totalPrices.product) {
                        totalPrice += totalPrices.product || 0;
                    }
                    if(totalPrices.installation) {
                        totalPrice += totalPrices.installation || 0;
                    }
                    if(totalPrices.service) {
                        totalPrice += totalPrices.service.fixedPrice || 0;
                    }
                    return totalPrice;
                }

                return totalPrices && totalPrices.service ? totalPrices.service.recurringPrice : 0;
            }

            return 0;
        }
    }
})();
