(function () {
    global.dashModule
        .controller('selectPackageCtrl', ['$scope', '$http', '$', '$translate', '$sce', 'utilsService', selectPackageCtrl])
        .directive('selectPackage', [selectPackageDirective]);

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

    function selectPackageCtrl($scope, $http, $, $translate, $sce, utilsService) {
        $scope.startSelectPackageModule = startSelectPackageModule;
        $scope.selectCustomer = selectCustomer;
        $scope.goToNextStep = goToNextStep;
        $scope.isStepVisible = isStepVisible;
        $scope.isVisibleToCustomer = isVisibleToCustomer;
        $scope.setVisible = setVisible;
        $scope.hasPrevStep = hasPrevStep;
        $scope.priceSum = priceSum;
        $scope.isSameCompany = isSameCompany;
        $scope.actionButton = 'NEXT';
        $scope.prevButton = '';
        $scope.customers = [];
        $scope.packageInfo = {};
        $scope.packageProducts = [];
        $scope.selectedCustomers = [];
        $scope.invoiceProcesses = [];
        $scope.priceList = {};
        $scope.title = {};
        $scope.showTitle = showTitle;
        $scope.hideTitle = hideTitle;
        $scope.getCustomerPrices = getCustomerPrices;
        $scope.data = {};
        $scope.showHideRemoveDialog = showHideRemoveDialog;
        $scope.idCustomer = 0;
        $scope.isRemoveDialogVisible = false;
        $scope.removeCustomerSpecificCommissions = removeCustomerSpecificCommissions;
        $scope.renderHtml = renderHtml;
        $scope.selectionSteps = {
            'set-default-prices': {
                current: 'set-default-prices',
                next: 'select-commissions',
                prev: '',
                isActionPromise: true,
                beforeAction: setDefaultPrices,
                action: getCustomers
            },
            'select-commissions': {
                current: 'select-commissions',
                next: '',
                prev: 'set-default-prices',
                isActionPromise: false,
                beforeAction: () => {
                    return true;
                },
                action: saveMyPackage
            },
        };
        $scope.step = $scope.selectionSteps['set-default-prices'];

        function startSelectPackageModule() {
            getPackageInfo();
            getBrokerPriceList();
        }

        function showTitle(idPayType) {
            $scope.title[idPayType] = true;
        }

        function hideTitle(idPayType) {
            $scope.title[idPayType] = false;
        }

        function isSameCompany(customer) {
            return parseInt(customer.isSameCompanyAsCl) === 1;
        }

        function isStepVisible(step) {
            return step === $scope.step.current;
        }

        function isVisibleToCustomer(customerPayType) {
            return customerPayType && customerPayType.visibleToCustomer ? 'glyphicon-eye-open' : 'glyphicon-eye-close';
        }

        function setVisible(customerPayType) {
            customerPayType.visibleToCustomer = !customerPayType.visibleToCustomer;
        }

        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 getCustomers() {
            const params = $.param({
                idPackage: global.getParameterByName('idPackage') || 0
            });

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

        function showCustomers(response) {
            if (response.data.length > 0) {
                $scope.selectedCustomers = [];
                $scope.customers = response.data;
                response.data.forEach((customer, key) => {
                    if (customer.selectedCustomer !== '0') {
                        selectCustomer(key);
                    }
                });
            }
        }

        function setDefaultPrices() {
            const defaultPrices = [];
            // 0 is for the default prices. Any other int value is the id of the customer
            $scope.priceList[0].forEach(priceObj => {
                defaultPrices.push({
                    idPayType: priceObj.idPayType,
                    defaultExtra: priceObj.defaultExtra,
                    defaultRecurent: priceObj.defaultRecurent,
                    defaultServicesRecurent: priceObj.defaultServicesRecurent,
                    visibleToCustomer: priceObj.visibleToCustomer
                });
            });

            const params = $.param({
                idPackage: global.getParameterByName('idPackage') || 0,
                defaultPrices: JSON.stringify(defaultPrices)
            });

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

        function showUpdateDefaultMessage(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' || messageObj.code === 'warning') {
                        goToNextStep('next', true);
                    }
                });
            }
        }

        function getComission(customerPrice, defaultValue, isSameCompanyAsCl) {
            const defaultPrice = parseInt(isSameCompanyAsCl) === 1 ? 0 : defaultValue;

            return parseFloat(customerPrice) || defaultPrice;
        }

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

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

        function setPriceList(response) {
            if (typeof response.data.brokerPrices !== 'undefined' && typeof response.data.commercialLeadPrices !== 'undefined') {
                const brokerPrices = response.data.brokerPrices;
                const commercialLeadPrices = response.data.commercialLeadPrices;
                // if 0, the prices are the ones default
                const idCustomer = response.data.idCustomer;

                brokerPrices[idCustomer].forEach((value) => {
                    value.minimalFixedPrice = parseFloat(value.minimalFixedPrice).toFixed(2);
                    value.minimalRecurentPrice = parseFloat(value.minimalRecurentPrice);
                    value.minimalServicesPrice = parseFloat(value.minimalServicesPrice);
                    value.defaultExtra = parseFloat(value.defaultExtra);
                    value.defaultRecurent = parseFloat(value.defaultRecurent);
                    value.defaultServicesRecurent = parseFloat(value.defaultServicesRecurent);
                    value.visibleToCustomer = (commercialLeadPrices[0] && commercialLeadPrices[0][value.idPayType]) ?
                        parseInt(commercialLeadPrices[0][value.idPayType].visibleToCustomer) :
                        1;
                    $scope.selectedCustomers.forEach(customer => {
                        const clPriceValues = (commercialLeadPrices[customer.id] && commercialLeadPrices[customer.id][value.idPayType]) ? commercialLeadPrices[customer.id][value.idPayType] : {};
                        const fixedCommission = getComission(clPriceValues.fixedExtra, value.defaultExtra, customer.isSameCompanyAsCl);
                        const recurentCommission = getComission(clPriceValues.recurentExtra, value.defaultRecurent, customer.isSameCompanyAsCl);
                        const recurentServicesCommission = getComission(clPriceValues.servicesExtra, value.defaultServicesRecurent, customer.isSameCompanyAsCl);
                        customer.prices = customer.prices || {};
                        customer.prices[value.idPayType] = {
                            visibleToCustomer: parseInt(clPriceValues.visibleToCustomer) || 0,
                            fixedCommission: fixedCommission,
                            recurentCommission: recurentCommission,
                            recurentServicesCommission: recurentServicesCommission,
                            packagePayPeriod: clPriceValues.packagePayPeriod || value.packagePayPeriod
                        };
                    });
                });
                $scope.priceList[idCustomer] = brokerPrices[idCustomer];
            }

        }

        function selectCustomer(customerKey) {
            const customerObject = $scope.customers[customerKey];
            const indexOfCustomer = $scope.selectedCustomers.indexOf(customerObject);

            if (indexOfCustomer >= 0) {
                $scope.selectedCustomers.splice(indexOfCustomer, 1);
            } else {
                $scope.selectedCustomers.push(customerObject);
                $scope.customers.splice(customerKey, 1);
                getBrokerPriceList(customerObject.id);
            }
        }

        function hasPrevStep() {
            return $scope.prevButton !== '';
        }

        function showWarning() {
            const translatedMessage = $translate.instant('packages.messages.SELECT_CUSTOMERS');
            utilsService.displayMessage('error', translatedMessage);
        }

        function goToNextStep(action, promiseFinished) {
            if ($scope.step.isActionPromise && !promiseFinished) {
                $scope.step.beforeAction();
            } else {
                const beforeACtionSuccesfull = promiseFinished || $scope.step.beforeAction();

                if (action === 'next') {
                    beforeACtionSuccesfull ? $scope.step.action() : showWarning();
                }

                if ($scope.step[action] !== '' && (beforeACtionSuccesfull || action === 'prev')) {
                    const newClassForActive = action === 'next' ? 'done-step' : 'inactive-step';
                    const removeClassForNew = action === 'next' ? 'inactive-step' : 'done-step';
                    $('.' + $scope.step.current).removeClass('active-step');
                    $('.' + $scope.step.current).addClass(newClassForActive);
                    $('.' + $scope.step[action]).removeClass(removeClassForNew);
                    $('.' + $scope.step[action]).addClass('active-step');
                    $scope.step = $scope.selectionSteps[$scope.step[action]];

                    $scope.actionButton = (action === 'next' && $scope.step.next === '') ? 'SAVE' : 'NEXT';
                    $scope.prevButton = (action === 'prev' && $scope.step.prev === '') ? '' : 'PREV';
                }
            }
        }

        function saveMyPackage() {
            const params = $.param({
                idPackage: global.getParameterByName('idPackage') || 0,
                selectedCustomers: JSON.stringify($scope.selectedCustomers)
            });

            $http({
                method: 'POST',
                url: 'packages/api/updateMyPackage',
                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);
                });
            }
        }

        function isNumber(value) {
            const reg = new RegExp('^([0-9]*\.[0-9]+|[0-9]+)$');

            return reg.test(value);
        }

        function priceSum(values) {
            let total = 0;
            let isValid = true;
            values.forEach((val) => {
                if (!isNumber(val)) {
                    isValid = false;
                }
                total += parseFloat(val);
            });

            return isValid ? total.toFixed(2) : 'invalid number';
        }

        function showHideRemoveDialog(idCustomer) {
            if (idCustomer) {
                $scope.idCustomer = idCustomer;
                $scope.customerToRemove = $scope.selectedCustomers.find(custObject => {
                    return custObject.id === idCustomer;
                });
            }
            $scope.$evalAsync(() => {
                $scope.isRemoveDialogVisible = !$scope.isRemoveDialogVisible;
            });
        }

        function getCustomerPrices(selectedCustomerKey) {
            if (selectedCustomerKey) {
                const idCustomer = $scope.customers[selectedCustomerKey].id;
                getBrokerPriceList(idCustomer);

                $scope.selectedCustomers.unshift($scope.customers[selectedCustomerKey]);
                $scope.customers.splice(selectedCustomerKey, 1);
            }
        }

        function removeCustomerSpecificCommissions() {
            if ($scope.idCustomer) {
                const removeCustObj = $scope.selectedCustomers.find(filterCustomerToRemove);
                const removeCustKey = $scope.selectedCustomers.findIndex(filterCustomerToRemove);

                $scope.selectedCustomers.splice(removeCustKey, 1);
                $scope.customers.push(removeCustObj);

                $scope.customers.sort((customerObject1, customerObject2) => {
                    var x = customerObject1.customer.toLowerCase();
                    var y = customerObject2.customer.toLowerCase();
                    if (x < y) {
                        return -1;
                    }
                    if (x > y) {
                        return 1;
                    }
                    return 0;
                });
            }
        }

        function filterCustomerToRemove(custObject) {
            return custObject.id === $scope.idCustomer;
        }

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