(function () {
    global.dashModule
        .controller('changeOrdersStepsCtrl', ['$scope', '$rootScope', '$http', '$', '$translate', '$compile', '$sce', 'utilsService', 'ordersUtilsService', 'ORDER_STATUSES_ICONS', 'ORDER_STATUSES', changeOrdersStepsCtrl])
        .directive('changeOrdersSteps', [changeOrdersStepsDirective]);
    function changeOrdersStepsDirective() {
        return {
            restrict: 'E',
            templateUrl: 'orders/html/changeOrdersStepsTemplate'
        };
    }

    function changeOrdersStepsCtrl($scope, $rootScope, $http, $, $translate, $compile, $sce, utilsService, ordersUtilsService, ORDER_STATUSES_ICONS, ORDER_STATUSES) {
        const expandedProces = [];
        let currentStepStatus = '';
        let firstInactivePosition = 0;
        let ordersDetailsMail = [];
        $scope.startOrdersStepsModule = startOrdersStepsModule;
        $scope.getStatusClass = getStatusClass;
        $scope.isNextButtonVisible = isNextButtonVisible;
        $scope.toggleInfo = toggleInfo;
        $scope.isEstimationDisabled = isEstimationDisabled;
        $scope.isStepVisible = isStepVisible;
        $scope.hasMoreSteps = hasMoreSteps;
        $scope.showAllSteps = showAllSteps;
        $scope.isExpanded = isExpanded;
        $scope.isExpandedAndFirstStepInactive = isExpandedAndFirstStepInactive;
        $scope.goToNextStep = goToNextStep;
        $scope.undoStep = undoStep;
        $scope.getOrderStatusIcon = getOrderStatusIcon;
        $scope.updatePackageEndOfLife = updatePackageEndOfLife;
        $scope.updateOrderEstimation = updateOrderEstimation;
        $scope.updateStepActualDate = updateStepActualDate;
        $scope.cancelOrder = cancelOrder;
        $scope.isCancelDialogVisible = false;
        $scope.isProcessDialogVisible = false;
        $scope.isNextDialogVisible = {};
        $scope.isUndoDialogVisible = {};
        $scope.showHideCancelDialog = showHideCancelDialog;
        $scope.showHideProcessDialog = showHideProcessDialog;
        $scope.showHideNextDialog = showHideNextDialog;
        $scope.isOrderOngoing = isOrderOngoing;
        $scope.setProcessForOrder = setProcessForOrder;
        $scope.hasNoSelectedProcess = hasNoSelectedProcess;
        $scope.updateStepCommentVisibility = updateStepCommentVisibility;
        $scope.isCommentVisible = isCommentVisible;
        $scope.stepVisibleForCustomer = stepVisibleForCustomer;
        $scope.setNewCommentVisibility = setNewCommentVisibility;
        $scope.canAddComment = canAddComment;
        $scope.hasAgreement = hasAgreement;
        $scope.formatStepText = formatStepText;
        $scope.isMyOrder = isMyOrder;
        $scope.hasExtraAction = ordersUtilsService.hasExtraAction;
        $scope.extraActionDirective = extraActionDirective;
        $scope.enableAssignBrokerEdit = enableAssignBrokerEdit;
        $scope.calculatePrice = ordersUtilsService.calculatePrice;
        $scope.processSteps = [];
        $scope.availableProcesses = [];
        $scope.ordersInfo = {};
        $scope.selections = [];
        $scope.brokers = [];
        $scope.selectedProcess = {};
        $scope.orderComments = [];
        $scope.orderOptions = [];
        $scope.isNextBtnDisabled = isNextBtnDisabled;
        $scope.getIconStepStatus = getIconStepStatus;
        $scope.getDisplayDescriptionClass = getDisplayDescriptionClass;
        $scope.isExtraActionOpen = {};
        $scope.updateStepComment = updateStepComment;
        $scope.updateOrderComment = updateOrderComment;
        $scope.isSupportMailBtnVisible = false;
        $scope.showHideSupportDialog = showHideSupportDialog;
        $scope.sendSupportMail = sendSupportMail;
        $scope.allowedLanguages = '';
        $scope.allowedLanguagesDescription = '';
        $scope.renderHtml = renderHtml;
        $scope.getStatusText = getStatusText;
        $scope.supportBtnNames = {
            confirmation: $translate.instant('orders.buttons.SEND'),
            cancel: $translate.instant('orders.buttons.CANCEL')
        };
        $scope.tinymceOptions = utilsService.getTynimceOptions({
            height: '150px'
        });

        function getStatusText(status){
            return ORDER_STATUSES[status] || status;
        }

        function renderHtml(htmlCode) {
            return $sce.trustAsHtml(htmlCode);
        }
        function startOrdersStepsModule() {
            ordersUtilsService.registerOrderFunction('showOrderInfo', showOrderInfo);
            getSystemAllowedLanguages();
            getOrderInfo();
            getOrderSteps();
            utilsService.registerFunction('isNextBtnDisabled', isNextBtnDisabled);
        }
        function isMyOrder(ordersInfo) {
            return Object.keys(ordersInfo).length !== 0;
        }
        function getOrderInfo() {
            ordersUtilsService.getOrderInfo();
        }
        function showOrderInfo(response) {
            if (typeof response.data.info !== 'undefined' &&
                typeof response.data.availableProcesses !== 'undefined' &&
                typeof response.data.packages !== 'undefined' &&
                typeof response.data.products !== 'undefined') {
                $scope.ordersInfo = response.data.info[0];
                $scope.packages = response.data.packages;
                $scope.products = response.data.products;
                $scope.orderComments = response.data.orderComments;
                $scope.orderOptions = response.data.orderOptions;
                $scope.additionalPackages = response.data.additionalPackages;
                $scope.selections = response.data.selections;
                $scope.availableProcesses = response.data.availableProcesses;
                $scope.orderDocuments = response.data.orderDocuments;
                ordersDetailsMail = {
                    idOrder: $scope.ordersInfo.id,
                    orderNumber: $scope.ordersInfo.orderNumber,
                    customer: $scope.ordersInfo.customer,
                    commercialLead: $scope.ordersInfo.commercialLead
                };
                getAvailabilityForSendSupportMail();
            }
        }
        function getOrderSteps() {
            const idOrder = global.getParameterByName('idOrder') || 0;
            const params = $.param({
                idOrder
            });
            $http({
                method: 'POST',
                url: 'orders/api/getOrderSteps',
                data: params
            }).then(showOrderSteps, utilsService.onHttpError);
        }
        function showOrderSteps(response) {
            const idOrder = global.getParameterByName('idOrder') || 0;
            if (typeof response.data === 'object') {
                $scope.processSteps = response.data;
                $.each($scope.processSteps, (processKey) => {
                    $scope.isExtraActionOpen[idOrder + '-' + processKey] = false;
                });
            }
        }
        function hasAgreement(packagePayPeriod, servicesContractPeriod) {
            return parseInt(packagePayPeriod) > 0 || parseInt(servicesContractPeriod) > 0;
        }
        function enableAssignBrokerEdit() {
            $('#enalbe-assign-edit').off('click');
            $('#enalbe-assign-edit').on('click', function () {
                const assignSelector = $(this).parent().find('.assign-broker');
                if (assignSelector.length) {
                    assignSelector.remove();
                } else {
                    const parent = $(this).parent();
                    const idOrder = parent.attr('id-order');
                    const directiveHtml = '<assign-broker id="assign-broker-' + idOrder + '" class="assign-broker" ng-controller="assignBrokerCtrl"></assign-broker>';
                    const scope = $rootScope.$new();
                    scope.idOrder = idOrder;
                    scope.onUpdate = getOrderInfo;
                    if ($scope.brokers.length > 0) {
                        scope.brokers = $scope.brokers;
                        const comp = $compile($(directiveHtml))(scope);
                        parent.append(comp);
                    } else {
                        $http({
                            method: 'POST',
                            url: 'orders/api/getBrokers'
                        }).then((response) => {
                            $scope.brokers = response.data;
                            scope.brokers = $scope.brokers;
                            const comp = $compile($(directiveHtml))(scope);
                            parent.append(comp);
                        }, utilsService.onHttpError);
                    }
                }
            });
        }
        function isCommentVisible(isVisible, isStepVisible) {
            if (isStepVisible === '1') {
                return isVisible === '1' ? 'glyphicon-eye-open' : 'glyphicon-eye-close';
            }
            return '';
        }
        function stepVisibleForCustomer(stepVisibleForCustomer) {
            return stepVisibleForCustomer === '1' ? 'glyphicon-eye-open' : 'glyphicon-eye-close';
        }
        function isNextButtonVisible(stepStatus) {
            return stepStatus === 'in-progress';
        }
        function getStatusClass(status) {
            const statusClasses = {
                'in-progress': 'step-in-progress',
                'done': 'step-done'
            };
            currentStepStatus = status;
            return statusClasses[status] || 'step-in-future';
        }
        function toggleInfo($event) {
            $($event.target)
                .parent()
                .parent()
                .find('.order-toggle-info')
                .toggle('slow');
            if ($($event.target).hasClass('glyphicon-plus-sign')) {
                $($event.target).removeClass('glyphicon-plus-sign');
                $($event.target).addClass('glyphicon-minus-sign');
            } else {
                $($event.target).removeClass('glyphicon-minus-sign');
                $($event.target).addClass('glyphicon-plus-sign');
            }
        }
        function isEstimationDisabled(status) {
            return status === 'inactive' || status === 'done';
        }
        function isStepVisible(position, steps, proc) {
            const currentStep = steps[position];
            const nextStep = steps[position + 1] || {};
            const prevStep = steps[position - 1] || {};
            return (expandedProces.indexOf(proc.idProcess) >= 0) || !(nextStep.status === 'done' || (currentStep.status === 'inactive' && prevStep.status === 'inactive'));
        }
        function hasMoreSteps(position, steps, proc, location) {
            const currentStepVisible = isStepVisible(position, steps, proc);
            const prevStepVisible = steps[position - 1] ? isStepVisible(position - 1, steps, proc) : true;
            const nextStepVisible = steps[position + 1] ? isStepVisible(position + 1, steps, proc) : true;
            return (location === 'start' && currentStepVisible && !prevStepVisible) ||
                (location === 'end' && currentStepVisible && !nextStepVisible);
        }
        function showAllSteps(proc) {
            const elementIndex = expandedProces.indexOf(proc.idProcess);
            if (elementIndex < 0) {
                expandedProces.push(proc.idProcess);
            } else {
                expandedProces.splice(elementIndex);
            }
        }
        function isExpanded(proc) {
            return expandedProces.indexOf(proc.idProcess) >= 0;
        }
        function isExpandedAndFirstStepInactive(processStep, step, stepPosition) {
            if (expandedProces.indexOf(processStep.idProcess) >= 0) {
                if (step.status === 'in-progress') {
                    firstInactivePosition = stepPosition + 1;
                }
                return firstInactivePosition && firstInactivePosition === stepPosition ? true : false;
            }
            return false;
        }
        function goToNextStep(fctParams) {
            const idNextBtn = fctParams.idOrder + '-' + fctParams.idProcess;
            ordersDetailsMail = Object.assign(ordersDetailsMail, {
                idProcess: fctParams.idProcess
            });
            if (!$scope.isExtraActionOpen[idNextBtn]) {
                const params = $.param({
                    idOrder: fctParams.idOrder,
                    idProcessStep: fctParams.idProcessStep,
                    ordersDetailsMail: JSON.stringify(ordersDetailsMail)
                });
                $http({
                    method: 'POST',
                    url: 'orders/api/goToNextStep',
                    data: params
                }).then((response) => {
                    showStepUpdateMessage(response, fctParams.idOrder);
                }, utilsService.onHttpError);
            }
        }
        function undoStep(fctParams) {
            const params = $.param({
                idOrder: fctParams.idOrder,
                idProcessStep: fctParams.idProcessStep
            });
            $http({
                method: 'POST',
                url: 'orders/api/undoStep',
                data: params
            }).then((response) => {
                showStepUpdateMessage(response, fctParams.idOrder);
            }, utilsService.onHttpError);
        }
        function showStepUpdateMessage(response, idOrder) {
            const stepsIdsForDeliveryDates = {
                firstStepEnabled: 5,
                lastStepEnabled: 6
            };
            ordersUtilsService.checkIfIsNextStepWanted(idOrder, 'setDeliveryDates', stepsIdsForDeliveryDates);
            ordersUtilsService.checkIfIsNextStepWanted(idOrder, 'installationScheduling', stepsIdsForDeliveryDates);
            updateMessage(response, startOrdersStepsModule);
        }
        function updateMessage(response, callback) {
            if (typeof response.data.messages !== 'undefined') {
                let shouldCallCallbackFunction = true;
                response.data.messages.forEach((messageObj) => {
                    const key = messageObj.key ? $translate.instant('orders.messages.' + messageObj.key) : '';
                    let translatedMessage = $translate.instant('orders.messages.' + messageObj.message);
                    translatedMessage = key !== '' ? key + ': ' + translatedMessage : translatedMessage;
                    if('additionalMessage' in messageObj) {
                        translatedMessage += messageObj.additionalMessage;
                    }
                    if (messageObj.message === 'ALLOWED_LANGUAGE') {
                        translatedMessage += $scope.allowedLanguages;
                    }
                    utilsService.displayMessage(messageObj.code, translatedMessage);
                });
                if (callback && shouldCallCallbackFunction) {
                    callback();
                }
            }
        }
        function getOrderStatusIcon(status) {
            return ORDER_STATUSES_ICONS[status];
        }
        function updateOrderEstimation(estimationDate) {
            const idOrder = global.getParameterByName('idOrder') || 0;
            const params = $.param({
                idOrder,
                estimationDate
            });
            $http({
                method: 'POST',
                url: 'orders/api/updateOrderEstimation',
                data: params
            }).then(showUpdateEstimation, utilsService.onHttpError);
        }
        function showUpdateEstimation(response) {
            updateMessage(response, getOrderInfo);
        }
        function updatePackageEndOfLife(endOfLifeDate, extraParams) {
            const params = $.param({
                idOrder: extraParams.idOrder,
                endOfLife: endOfLifeDate,
                idPackage: extraParams.idPackage,
                ordersDetailsMail: JSON.stringify(ordersDetailsMail)
            });
            $http({
                method: 'POST',
                url: 'orders/api/updatePackageEndOfLife',
                data: params
            }).then(showUpdateEndOfLife, utilsService.onHttpError);
        }
        function showUpdateEndOfLife(response) {
            updateMessage(response, getOrderInfo);
        }
        function updateStepActualDate(actualDate, step) {
            const params = $.param({
                idOrder: step.idOrder || 0,
                idProcessStep: step.idProcessStep || 0,
                actualDate,
                ordersDetailsMail: JSON.stringify(ordersDetailsMail)
            });
            $http({
                method: 'POST',
                url: 'orders/api/updateStepActualDate',
                data: params
            }).then(showUpdateEstimation, utilsService.onHttpError);
        }
        function updateStepComment(comment, step) {
            if (typeof comment !== 'undefined' && comment && step) {
                const params = $.param({
                    idOrder: step.idOrder || 0,
                    idProcessStep: step.idProcessStep || 0,
                    comment,
                    isVisible: step.isNewCommentVisible,
                    ordersDetailsMail: JSON.stringify(ordersDetailsMail)
                });
                $http({
                    method: 'POST',
                    url: 'orders/api/updateStepComment',
                    data: params
                }).then(showUpdateStepComment, utilsService.onHttpError);
            }
        }
        function showUpdateStepComment(response) {
            updateMessage(response, startOrdersStepsModule);
        }
        function updateOrderComment() {
            if (typeof $scope.ordersInfo.orderCommentText !== 'undefined' && $scope.ordersInfo.orderCommentText !== '') {
                const params = $.param({
                    idOrder: global.getParameterByName('idOrder') || 0,
                    comment: $scope.ordersInfo.orderCommentText,
                    ordersDetailsMail: JSON.stringify(ordersDetailsMail)
                });
                $http({
                    method: 'POST',
                    url: 'orders/api/updateOrderComment',
                    data: params
                }).then(showUpdateOrderComment, utilsService.onHttpError);
            }
        }
        function showUpdateOrderComment(response) {
            updateMessage(response, startOrdersStepsModule);
        }
        function showHideCancelDialog() {
            $scope.$evalAsync(() => {
                $scope.isCancelDialogVisible = !$scope.isCancelDialogVisible;
            });
        }
        function showHideNextDialog(params) {
            const idNextBtn = params.idOrder + '-' + params.idProcess;
            $scope.$evalAsync(() => {
                if (params.action === 'next' && !$scope.isExtraActionOpen[idNextBtn]) {
                    $scope.isNextDialogVisible[params.idProcess] = !$scope.isNextDialogVisible[params.idProcess];
                }
                if (params.action === 'undo') {
                    $scope.isUndoDialogVisible[params.idProcess] = !$scope.isUndoDialogVisible[params.idProcess];
                }
            });
        }
        function showHideProcessDialog(selectedProcess) {
            $scope.selectedProcess = selectedProcess;
            $scope.$evalAsync(() => {
                $scope.isProcessDialogVisible = !$scope.isProcessDialogVisible;
            });
        }
        function showHideSupportDialog() {
            $scope.$evalAsync(() => {
                $scope.isSupportMailBtnVisible = !$scope.isSupportMailBtnVisible;
            });
        }
        function cancelOrder(idOrder) {
            const params = $.param({
                idOrder,
                ordersDetailsMail: JSON.stringify(ordersDetailsMail)
            });
            $http({
                method: 'POST',
                url: 'orders/api/cancelOrder',
                data: params
            }).then(showOrderCancelMessage, utilsService.onHttpError);
        }
        function showOrderCancelMessage(response) {
            updateMessage(response, startOrdersStepsModule);
        }
        function isOrderOngoing(status) {
            const orderFinishedStatuses = ['canceled', 'production', 'end-of-life'];
            return orderFinishedStatuses.indexOf(status) === -1;
        }
        function setProcessForOrder(selectedProcess) {
            const params = $.param({
                idOrder: global.getParameterByName('idOrder') || 0,
                idProcess: selectedProcess.idProcess,
                ordersDetailsMail: JSON.stringify(ordersDetailsMail)
            });
            $scope.selectedProcess = selectedProcess;
            $http({
                method: 'POST',
                url: 'orders/api/setProcessForOrder',
                data: params
            }).then(showProcessSelectedMessage, utilsService.onHttpError);
        }
        function showProcessSelectedMessage(response) {
            updateMessage(response, startOrdersStepsModule);
        }
        function hasNoSelectedProcess(status) {
            return status === 'open' ? true : false;
        }
        function updateStepCommentVisibility(commentObj) {
            const isVisibleNewVal = commentObj.isVisible === '1' ? 0 : 1;
            const params = $.param({
                idComment: commentObj.id,
                isVisible: isVisibleNewVal,
                ordersDetailsMail: JSON.stringify(ordersDetailsMail)
            });
            $http({
                method: 'POST',
                url: 'orders/api/updateStepCommentVisibility',
                data: params
            }).then(showUpdateStepComment, utilsService.onHttpError);
        }
        function setNewCommentVisibility(step) {
            step.isNewCommentVisible = step.isNewCommentVisible === '1' ? '0' : '1';
        }
        function canAddComment(step) {
            return step.status === 'in-progress';
        }
        function formatStepText(stepStatus) {
            return stepStatus.replace('-', '_');
        }
        function extraActionDirective(step) {
            const directiveHtml = '<' + step.actionCode + '></' + step.actionCode + '>';
            const scope = $rootScope.$new();
            scope.step = step;
            scope.packages = $scope.packages;
            const comp = $compile($(directiveHtml))(scope);
            $scope.$evalAsync(() => {
                $('#extra-action-' + step.idProcess).append(comp);
            });
        }
        function isNextBtnDisabled(stepInfo) {
            const idNextBtn = stepInfo.idOrder + '-' + stepInfo.idProcess;
            $scope.isExtraActionOpen[idNextBtn] = stepInfo.isNextButtonDisabled;
        }
        function getIconStepStatus() {
            return currentStepStatus && currentStepStatus === 'in-progress' ? 'glyphicon-minus-sign' : 'glyphicon-plus-sign';
        }
        function getDisplayDescriptionClass() {
            return currentStepStatus && currentStepStatus === 'in-progress' ? '' : 'order-step-description-display';
        }
        function getAvailabilityForSendSupportMail() {
            const params = $.param({
                idOrder: $scope.ordersInfo.id
            });
            $http({
                method: 'POST',
                url: 'orders/api/getAvailabilityForSendSupportMail',
                data: params
            }).then(setAvailabilityForSendSupportMail, utilsService.onHttpError);
        }
        function setAvailabilityForSendSupportMail(response) {
            if (typeof response.data !== 'undefined') {
                $scope.isSendSupportMailBtnAvailable = response.data;
            }
        }
        function sendSupportMail(userText) {
            if (!userText) {
                const translatedMessage = $translate.instant('orders.messages.MAIL_TEXT_EMPTY');
                utilsService.displayMessage('error', translatedMessage);
            } else {
                const params = $.param({
                    ordersInfo: JSON.stringify($scope.ordersInfo),
                    orderPackages: JSON.stringify($scope.packages),
                    userText
                });
                $http({
                    method: 'POST',
                    url: 'orders/api/sendSupportMail',
                    data: params
                }).then(updateMessage, utilsService.onHttpError);
            }
        }
        function getSystemAllowedLanguages() {
            $http({
                method: 'POST',
                url: 'orders/api/getSystemAllowedLanguages'
            }).then(setSystemAllowedLanguages, utilsService.onHttpError);
        }
        function setSystemAllowedLanguages(response) {
            if (typeof response.data !== 'undefined' && Object.keys(response.data).length > 0) {
                if(!$scope.allowedLanguages) {
                    response.data.languages.forEach(language => {
                        $scope.allowedLanguages = $scope.allowedLanguages ? $scope.allowedLanguages + ', ' + language : language;
                    });
                }
                const translatedMessage = $translate.instant('orders.messages.ALLOWED_LANGUAGE');
                if (!$scope.allowedLanguagesDescription) {
                    $scope.allowedLanguagesDescription = translatedMessage + $scope.allowedLanguages + '!';
                }
            }
        }
    }
})();
