(function () {
    global.dashModule
        .directive('packageOptions', packageOptionsDirective)
        .controller('packageOptionsCtrl', ['$scope', '$', '$http', '$translate', 'utilsService', packageOptionsCtrl]);

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

    function packageOptionsCtrl($scope, $, $http, $translate, utilsService) {
        let groupCounter = 0;
        $scope.getOptionsAndPackages = getOptionsAndPackages;
        $scope.selectPackage = selectPackage;
        $scope.getPackageClass = getPackageClass;
        $scope.isDefault = isDefault;
        $scope.addGroup = addGroup;
        $scope.removeGroup = removeGroup;
        $scope.packageDragStart = packageDragStart;
        $scope.packageDragStop = packageDragStop;
        $scope.packageOptionAdded = packageOptionAdded;
        $scope.packageOptionRemoved = packageOptionRemoved;
        $scope.setDefaultOption = setDefaultOption;
        $scope.updatePackageOptions = updatePackageOptions;
        $scope.packageAdditionalAdded = packageAdditionalAdded;
        $scope.packageAdditionalRemoved = packageAdditionalRemoved;
        $scope.getPackageWarningClass = getPackageWarningClass;
        $scope.options = [];
        $scope.standardPackages = [];
        $scope.selectedPackage = {};

        function getOptionsAndPackages() {
            $http({
                method: 'POST',
                url: 'packages/api/getOptionsAndPackages'
            }).then(setDocumentsAndPackages, utilsService.onHttpError);
        }

        function setDocumentsAndPackages(response) {
            if (response.data && response.data.option && response.data.standard && response.data.additional) {
                const selectedKey = Object.keys(response.data.standard)[0];
                $scope.options = response.data.options;
                $scope.selectedPackage = response.data.standard[selectedKey] || {};
                $scope.standardPackages = response.data.standard;
                $scope.options = response.data.option;
                $scope.additionalPackages = response.data.additional;
                if(selectedKey){
                    chekPricesForSelectedPackage();
                }

                $scope.options.forEach(hideOptionPackages);
                $scope.additionalPackages.forEach(hideOptionPackages);
            } else {
                $scope.options = [];
                $scope.standardPackages = [];
                $scope.additionalPackages = [];
            }
        }

        function chekPricesForSelectedPackage(){
            $scope.selectedPackage.groups.forEach((group) => {
                group.options.forEach((option) => {
                    option.hasAllPrices = $scope.selectedPackage.prices.length === option.prices.length &&
                        $scope.selectedPackage.prices.every((value, i) => value === option.prices[i]);
                });
            });
            $scope.selectedPackage.additionalPackages.forEach((additionalPackage) => {
                additionalPackage.hasAllPrices = $scope.selectedPackage.prices.length === additionalPackage.prices.length &&
                    $scope.selectedPackage.prices.every((value, i) => value === additionalPackage.prices[i]);
            });
        }

        function hideOptionPackages(currentPackage) {
            const ID_OPTION_TYPE = 2;
            const ID_ADDITIONAL_TYPE = 3;
            let iscurrentPackageInArray = false;

            if (currentPackage.countryCode !== $scope.selectedPackage.countryCode) {
                currentPackage.isAvailable = false;

                return;
            }

            currentPackage.hasAllPrices = $scope.selectedPackage.prices.length === currentPackage.prices.length &&
                $scope.selectedPackage.prices.every((value, i) => value === currentPackage.prices[i]);

            if ($scope.selectedPackage.groups && parseInt(currentPackage.idPackageType) === ID_OPTION_TYPE) {
                $scope.selectedPackage.groups.forEach((group) => {
                    iscurrentPackageInArray = iscurrentPackageInArray || findOptionPackage(group, currentPackage);
                });
            }
            if ($scope.selectedPackage.additionalPackages && parseInt(currentPackage.idPackageType) === ID_ADDITIONAL_TYPE) {
                iscurrentPackageInArray = $scope.selectedPackage.additionalPackages.find((additional) => {
                    return additional.idPackage === currentPackage.idPackage;
                });
            }

            currentPackage.isAvailable = !iscurrentPackageInArray;
        }

        function findOptionPackage(group, currentPackage) {
            return group.options.find((option) => {
                return option.idPackage === currentPackage.idPackage;
            });
        }

        function selectPackage(selected) {
            $scope.selectedPackage = selected;
            chekPricesForSelectedPackage();
            $scope.options.forEach(hideOptionPackages);
            $scope.additionalPackages.forEach(hideOptionPackages);
        }

        function getPackageClass(curent) {
            return curent === $scope.selectedPackage ? 'selected-package' : '';
        }

        function isDefault(option) {
            return parseInt(option.isDefault) === 1;
        }

        function generateGroup() {
            groupCounter++;

            return {
                groupName: '',
                idGroup: 'new-' + groupCounter,
                isNewGroup: 1,
                options: []
            };
        }

        function addGroup() {
            $scope.selectedPackage.groups.push(generateGroup());
        }

        function removeGroup(index) {
            $scope.selectedPackage.groups.splice(index, 1);
            $scope.options.forEach(hideOptionPackages);
        }

        function packageDragStart(event, ui, selector) {
            $('#' + selector).css({
                overflow: 'visible',
            });
            $('.' + $(ui.helper).attr('drop-to')).css({
                background: 'rgba(92, 184, 92, 0.3)'
            });
        }

        function packageDragStop(event, ui, selector) {
            $('#' + selector).css({
                'overflow': 'auto'
            });
            $('.' + $(ui.helper).attr('drop-to')).css({
                background: 'none'
            });
        }

        function packageOptionRemoved(event, ui, dropContainer) {
            const dropToSelector = $(ui.helper).attr('drop-to');
            const idPackage = $(ui.helper).attr('id-option-package');
            const idGroup = $(ui.helper).attr('id-group');

            if (dropContainer !== dropToSelector) {
                return;
            }

            const group = $scope.selectedPackage.groups.find((group) => {
                return group.idGroup === idGroup;
            });
            const dragedPackageIndex = group.options.findIndex((pkg) => {
                return pkg.idPackage === idPackage;
            });
            const wasDefault = parseInt(group.options[dragedPackageIndex].isDefault) === 1;

            group.options.splice(dragedPackageIndex, 1);

            if (wasDefault && group.options.length) {
                setDefaultOption(group, group.options[0]);
            }
            $scope.options.forEach(hideOptionPackages);
        }

        function packageOptionAdded(event, ui, dropContainer, group) {
            const dropToSelector = $(ui.helper).attr('drop-to');
            const idPackage = $(ui.helper).attr('id-option-package');

            if (dropContainer !== dropToSelector) {
                return;
            }

            const dragedPackage = $scope.options.find((pkg) => {
                return pkg.idPackage === idPackage;
            });
            dragedPackage.isDefault = group.options.length ? 0 : 1;

            group.options.push(dragedPackage);
            $scope.options.forEach(hideOptionPackages);
        }

        function packageAdditionalRemoved(event, ui, dropContainer) {
            const dropToSelector = $(ui.helper).attr('drop-to');
            const idPackage = $(ui.helper).attr('id-additional-package');
            const additionalList = $scope.selectedPackage.additionalPackages;

            if (dropContainer !== dropToSelector) {
                return;
            }
            const dragedPackageIndex = additionalList.findIndex((pkg) => {
                return pkg.idPackage === idPackage;
            });

            additionalList.splice(dragedPackageIndex, 1);
            $scope.additionalPackages.forEach(hideOptionPackages);
        }

        function packageAdditionalAdded(event, ui, dropContainer) {
            const dropToSelector = $(ui.helper).attr('drop-to');
            const idPackage = $(ui.helper).attr('id-additional-package');

            if (dropContainer !== dropToSelector) {
                return;
            }

            const dragedPackage = $scope.additionalPackages.find((pkg) => {
                return pkg.idPackage === idPackage;
            });

            $scope.selectedPackage.additionalPackages.push(dragedPackage);
            $scope.additionalPackages.forEach(hideOptionPackages);
        }

        function setDefaultOption(group, option) {
            group.options.forEach((opt) => {
                opt.isDefault = 0;
            });

            option.isDefault = 1;
        }

        function updatePackageOptions() {
            const params = $.param({
                idPackage: $scope.selectedPackage.idPackage,
                groups: JSON.stringify($scope.selectedPackage.groups),
                additionalPackages: JSON.stringify($scope.selectedPackage.additionalPackages)
            });

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

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

        function getPackageWarningClass(arePricesAvailable) {
            return arePricesAvailable ? '' : 'alert-warning';
        }
    }
})();
