(function () {
    global.dashModule
        .directive('createProcessSteps', createProcessStepsDirective)
        .controller('createProcessStepsCtrl', ['$scope', '$http', '$', '$timeout', '$translate', 'utilsService', createProcessStepsCtrl]);

    function createProcessStepsDirective() {
        return {
            restrict: 'E',
            templateUrl: 'processes/html/createProcessTemplate'
        };
    }

    function createProcessStepsCtrl($scope, $http, $, $timeout, $translate, utilsService) {
        let idStepAdded;
        let isStepVisible = true;
        const messageTranslatePath = 'processes.messages.';
        $scope.packages = {};
        $scope.initProcessCreation = initProcessCreation;
        $scope.addProcessStep = addProcessStep;
        $scope.addProcess = addProcess;
        $scope.processListsTitle = getProcessTitleTranslation;
        $scope.shouldShowIcon = shouldShowIcon;
        $scope.isProcessFormValid = isProcessFormValid;
        $scope.getStepsForProcess = getStepsForProcess;
        $scope.getStepPadding = getStepPadding;
        $scope.getStepNumber = getStepNumber;
        $scope.selectedProcesses = [];
        $scope.isStepVisibleToCustomer = isStepVisibleToCustomer;
        $scope.setVisible = setVisible;
        $scope.isVisibleToCustomer = isVisibleToCustomer;
        $scope.processSteps = [];
        $scope.getExtraActionDescription = getExtraActionDescription;
        $scope.countries = [];
        $scope.selectedCountry = null;
        $scope.tinymceOptions = utilsService.getTynimceOptions();

        function createOptions(stepPlace) {
            var options = {
                placeholder: 'create-processes-products-display',
                connectWith: '.processes-list',
                start: function () {
                    if (stepPlace === 'available') {
                        $('#create-processes-step-dragndrop-process').addClass('allowed-drop-zone');
                    }
                },
                stop: function () {
                    if (stepPlace === 'available') {
                        $('#create-processes-step-dragndrop-process').removeClass('allowed-drop-zone');
                    }
                }
            };
            return options;
        }

        $scope.sortableOptionsList = {
            available: createOptions('available'),
            process: createOptions('process')
        };

        function initProcessCreation(processSteps, onProcessCreated) {
            $scope.processSteps = processSteps || [];
            $scope.onProcessCreated = onProcessCreated;
            getCountries();
            displayProcessSteps(getStepsForProcess);
        }

        function getCountries() {
            const params = $.param({
                getArray: true
            });
            $http({
                method: 'POST',
                data: params,
                url: 'countries/api/getAllCountries'
            }).then(setCountries, utilsService.onHttpError);
        }

        function setCountries(response) {
            if (response.data) {
                $scope.countries = response.data;
            }
        }

        function displayProcessSteps(successCallback) {
            $http({
                method: 'GET',
                url: 'processes/api/getProcessSteps'
            }).then(successCallback, utilsService.onHttpError);
        }

        function getStepsForProcess(response) {
            if (!angular.equals(response.data, {})) {
                $scope.availableSteps = response.data.steps;
                if($scope.processSteps){
                    $scope.availableSteps = $scope.availableSteps.filter((availableStep) => {
                        return !$scope.processSteps.find((selectedStep) => {
                            return selectedStep.id === availableStep.id;
                        });
                    });
                }
                getUserTypes();
                getExtraActionsAvailable();
            }
        }

        function addProcessStep() {
            const params = $.param({
                shortDesc: $scope.processStepShortDesc,
                fullDesc: $scope.processStepFullDesc,
                idUserType: $scope.selectedUserTypeId,
                isStepVisible: isStepVisible ? 1 : 0,
                extraActionCode: $scope.selectedExtraAction || ''
            });

            $http({
                method: 'POST',
                url: 'processes/api/addProcessStep',
                data: params
            }).then(addProcessStepConfirmation, utilsService.onHttpError);
        }

        function addProcessStepConfirmation(response) {
            if (response.data.messageData) {
                const translationData = {
                    stepName: $scope.processStepShortDesc
                };

                response.data.messageData.forEach(messageInfo => {
                    if (messageInfo.code === 'success') {
                        idStepAdded = response.data.idInserted;
                        $scope.$parent.processStepShortDesc = '';
                        $scope.$parent.processStepFullDesc = '';
                        isStepVisible = true;
                        displayProcessSteps(updateProcessSteps);
                    } else {
                        if (messageInfo.type && messageInfo.limit) {
                            translationData.type = messageInfo.type;
                            translationData.limit = messageInfo.limit;
                        }
                    }
                    const message = $translate.instant(messageTranslatePath + messageInfo.message, translationData);
                    utilsService.displayMessage(messageInfo.code, message);
                });
            } else {
                throwServerError();
            }
        }

        function updateProcessSteps(response) {
            if (response.data.steps.length) {
                const newStepAdded = response.data.steps.find(findAddedProcessStep);
                $scope.availableSteps.push(newStepAdded);
                $scope.availableSteps.sort(compareStepNames);
            }
        }

        function findAddedProcessStep(stepData) {
            return parseInt(stepData.id) === idStepAdded;
        }

        function addProcess() {
            if ($scope.processName && $scope.processSteps.length > 0) {
                const params = $.param({
                    data: JSON.stringify($scope.processSteps),
                    processName: $scope.processName,
                    idCountry: $scope.selectedCountry
                });

                $http({
                    method: 'POST',
                    url: 'processes/api/addProcess',
                    data: params
                }).then(processConfirmationMessage, utilsService.onHttpError);
            } else {
                utilsService.displayMessage('error', $translate.instant(messageTranslatePath + 'PROCESS_DATA_MISSING'));
            }
        }

        function processConfirmationMessage(response) {
            if (response.data.messageData) {
                const translationData = {
                    processName: $scope.processName
                };
                response.data.messageData.forEach(messageInfo => {
                    if (messageInfo.code === 'success') {
                        $scope.processName = '';
                        $scope.availableSteps = $scope.availableSteps.concat($scope.processSteps);
                        $scope.availableSteps.sort(compareStepNames);
                        $scope.processSteps = [];

                        if($scope.onProcessCreated){
                            $scope.onProcessCreated();
                        }
                    } else {
                        $('#create-processes-process-name').focus();
                        if (messageInfo.type && messageInfo.limit) {
                            translationData.type = messageInfo.type;
                            translationData.limit = messageInfo.limit;
                        }
                    }
                    const message = $translate.instant(messageTranslatePath + messageInfo.message, translationData);
                    utilsService.displayMessage(messageInfo.code, message);
                });
            } else {
                throwServerError();
            }
        }

        function shouldShowIcon(name) {
            return name === 'steps';
        }

        function getProcessTitleTranslation(name) {
            return 'processes.labels.' + name.toUpperCase();
        }

        function getUserTypes() {
            $http({
                method: 'GET',
                url: 'processes/api/getUserTypes',
            }).then(setUserTypes, utilsService.onHttpError);
        }

        function setUserTypes(response) {
            if (response.data.length) {
                response.data.forEach(userType => {
                    userType.type = userType.type.charAt(0).toUpperCase() + userType.type.slice(1);
                    userType.type = userType.type.replace('_', ' ');
                });
                $scope.userTypes = response.data;
            }
        }

        function getExtraActionsAvailable() {
            $http({
                method: 'POST',
                url: 'processes/api/getExtraActionsAvailable',
            }).then(setExtraActionsAvailable, utilsService.onHttpError);
        }

        function setExtraActionsAvailable(response) {
            if (response.data.length) {
                response.data.forEach(extraAction => {
                    extraAction.name = extraAction.actionCode.charAt(0).toUpperCase() + extraAction.actionCode.slice(1);
                    extraAction.name = extraAction.name.replace('-', ' ');
                });
                $scope.extraActions = response.data;
            }
        }

        function isProcessFormValid() {
            return $scope.processName && $scope.processSteps.length > 0;
        }

        function getStepPadding(position) {
            return (position + 1) * 2;
        }

        function getStepNumber(position) {
            $scope.processSteps[position].stepNumber = position + 1;
            return position + 1;
        }

        function throwServerError() {
            const errorMessage = $translate.instant('processes.messages.SERVER_ERROR');
            utilsService.displayMessage('error', errorMessage);
        }

        function isStepVisibleToCustomer() {
            return isStepVisible ? 'glyphicon-eye-open' : 'glyphicon-eye-close';
        }

        function setVisible() {
            isStepVisible = !isStepVisible;
        }

        function isVisibleToCustomer(stepVisibleInfo) {
            return stepVisibleInfo === '1' ? 'glyphicon-eye-open' : 'glyphicon-eye-close';
        }

        function getExtraActionDescription() {
            const selectedActionObj = $scope.extraActions.filter((action) => {
                return action.idActionCode === $scope.selectedExtraAction;
            });

            if (selectedActionObj.length) {
                const translatedName = selectedActionObj[0].actionCode.replace('-', '_');
                return $translate.instant('processes.messages.' + translatedName);
            }

            return '';
        }

        function compareStepNames(stepA, stepB) {
            if (stepA.shortDesc < stepB.shortDesc) {
                return -1;
            }

            if (stepA.shortDesc > stepB.shortDesc) {
                return 1;
            }

            return 0;
        }
    }
})();
