(function () {
    global.dashModule
        .controller('installationSchedulerCtrl', ['$scope', '$', '$http', '$translate', '$timeout', 'Upload', 'utilsService', 'ordersUtilsService', installationSchedulerCtrl])
        .directive('installationScheduler', [installationSchedulerDirective]);

    function installationSchedulerDirective() {
        return {
            restrict: 'E'
        };
    }

    function installationSchedulerCtrl($scope, $, $http, $translate, $timeout, Upload, utilsService, ordersUtilsService) {
        const idOrder = global.getParameterByName('idOrder');
        const idPackage = $scope.$parent.orderPackage.idPackage;
        const stepsIdsForInstallation = {
            firstStepEnabled: 5,
            lastStepEnabled: 6
        };
        $scope.idPackage = idPackage;
        $scope.idOrder = idOrder;
        $scope.getInstallationDetails = getInstallationDetails;
        $scope.installationDates = [];
        $scope.earliestInstallationDate = () => {
            return ordersUtilsService.getEarliestInstallationDate(idOrder);
        };
        $scope.saveInstallationForPackage = saveInstallationForPackage;
        $scope.installCompany = {};
        $scope.multipleInstallCompanies = false;
        $scope.updateInstallationDate = updateInstallationDate;
        $scope.getIcon = getIcon;
        $scope.shouldShowAddNewDate = shouldShowAddNewDate;
        $scope.showAddNewDate = true;
        $scope.isRemoveBtnVisible = isRemoveBtnVisible;
        $scope.isDateProposedByMe = isDateProposedByMe;
        $scope.removeMyDate = removeMyDate;
        $scope.isAcceptDialogVisible = {};
        $scope.isDeclineDialogVisible = {};
        $scope.isRemoveDialogVisible = {};
        $scope.showHideAcceptDialog = showHideAcceptDialog;
        $scope.showHideDeclineDialog = showHideDeclineDialog;
        $scope.showHideRemoveDialog = showHideRemoveDialog;
        $scope.isInstallationInOrder = true;
        $scope.isInstallationSet = false;
        $scope.canUserAcceptOrDecline = canUserAcceptOrDecline;
        $scope.userButtonAction = userButtonAction;
        $scope.isMyInstallationCompany = false;
        $scope.isInstallationSchedulingDisabled = () => {
            const schedulingDisabled = ordersUtilsService.isComponentDisabled(idOrder, 'installationScheduling') || $scope.earliestInstallationDate() === '-';
            $scope.optionClass = schedulingDisabled ? 'installation-company-disabled' : '';

            return schedulingDisabled;
        };
        $scope.isInstallCompanySelectedAndScheduleDisabled = () => {
            return $scope.isInstallationSchedulingDisabled() || !$scope.isInstallationSet;
        };
        utilsService.registerFunction('setMinDateAvailable', setMinDateAvailable);
        $scope.installationDocuments = {};
        $scope.uploadFile = uploadFile;
        $scope.removeInstallDocument = removeInstallDocument;
        $scope.isDialogVisible = {};
        $scope.showHideDialog = showHideDialog;
        $scope.showHideInstallationDialog = showHideInstallationDialog;
        $scope.isInstallationDialogVisible = {};
        $scope.isChangeInstallationAvailable = false;
        $scope.activateChangeInstallation = activateChangeInstallation;
        $scope.showHideChangingInstallationDialog = showHideChangingInstallationDialog;
        $scope.isChangingInstallationDialogVisible = false;
        $scope.showDateDetails = showDateDetails;

        function getInstallationInformations() {
            getInstallCompaniesForPackage();
            getConfirmationInstallationDates();
            getInstallationDocuments();
            checkIfDateAlreadyAccepted();
            utilsService.registerFunction('getConfirmationInstallationDates', getConfirmationInstallationDates);
        }

        function getInstallationDetails() {
            getInstallationInformations();
            ordersUtilsService.checkIfIsNextStepWanted(idOrder, 'installationScheduling', stepsIdsForInstallation);
            ordersUtilsService.getEarliestInstallationDateFromDb(idOrder);
        }

        function setMinDateAvailable(paramData) {
            $('#installation-date-propose-' + paramData.idPackage).datepicker('option', 'minDate', new Date(paramData.minDate));
        }

        function getConfirmationInstallationDates() {
            const params = $.param({
                idOrder,
                idPackage
            });

            $http({
                method: 'POST',
                url: 'orders/api/getInstallationDates',
                data: params
            }).then(setInstallationDates, utilsService.onHttpError);
        }

        function setInstallationDates(response) {
            if (response.data && Object.keys(response.data).length) {
                $scope.confirmationDates = response.data;
                $scope.showAddNewDate = false;
            } else {
                $scope.confirmationDates = {};
                $scope.showAddNewDate = true;
            }
        }

        function getInstallCompaniesForPackage() {
            const params = $.param({
                idOrder,
                idPackage
            });

            $http({
                method: 'POST',
                data: params,
                url: 'orders/api/getInstallCompaniesForPackage'
            }).then(setInstallationCompanies, utilsService.onHttpError);
        }

        function setInstallationCompanies(response) {
            if (typeof response.data !== 'undefined') {
                const availableInstallationCompanies = response.data.available ? response.data.available : [];
                const selectedInstallationCompany = response.data.selected ? response.data.selected : [];
                $scope.isMyInstallationCompany = response.data.isMyInstallationCompany;

                if (availableInstallationCompanies.length === 0 && selectedInstallationCompany.length === 0) {
                    $scope.isInstallationInOrder = false;
                } else if (availableInstallationCompanies.length > 0) {
                    if (availableInstallationCompanies.length === 1) {
                        $scope.multipleInstallCompanies = false;
                        $scope.installationCompany = availableInstallationCompanies[0];
                        $scope.isInstallationSet = true;
                    } else {
                        $scope.multipleInstallCompanies = true;
                        if (selectedInstallationCompany.length > 0) {
                            $scope.installationCompany = selectedInstallationCompany[0];
                            $scope.isInstallationSet = true;
                        }
                        $scope.installCompanies = availableInstallationCompanies;
                    }
                }
                $scope.isChangeInstallationAvailable = $scope.multipleInstallCompanies && $scope.isInstallationSet;
            }
        }

        function getInstallationDocuments() {
            const params = $.param({
                idOrder,
                idPackage,
                documentType: 'installationProtocol'
            });

            $http({
                method: 'POST',
                url: 'orders/api/getOrderDocumentsPerType',
                data: params
            }).then(setInstallationDocuments, utilsService.onHttpError);
        }

        function setInstallationDocuments(response) {
            if (typeof response.data !== 'undefined') {
                $scope.installationDocuments = response.data;
            }
        }

        function saveInstallationForPackage(idInstallation) {
            const params = $.param({
                idOrder,
                idPackage,
                idInstallation
            });

            $http({
                method: 'POST',
                data: params,
                url: 'orders/api/saveInstallationCompany'
            }).then(displayMessage, utilsService.onHttpError);
        }

        function checkIfDateAlreadyAccepted() {
            const params = $.param({
                idOrder,
                idPackage
            });

            $http({
                method: 'POST',
                url: 'orders/api/checkIfDateAlreadyAccepted',
                data: params
            }).then(setInstallationAlreadyAccepted, utilsService.onHttpError);
        }

        function setInstallationAlreadyAccepted(response) {
            if (typeof response !== 'undefined') {
                $scope.isDateAlreadyAccepted = response.data;
            }
        }

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

                    if (messageObj.code === 'success') {
                        $scope.installationDate = '';
                        getInstallationInformations();
                    }
                });
            }
        }

        function updateInstallationDate(installationDate, status = 'proposed') {
            if (Date.parse(installationDate)) {
                const params = $.param({
                    idOrder,
                    idPackage,
                    installationDate,
                    status
                });

                $http({
                    method: 'POST',
                    url: 'orders/api/updateInstallationDate',
                    data: params
                }).then(displayMessage, utilsService.onHttpError);
            } else {
                const translatedMessage = $translate.instant('orders.messages.WRONG_DATE_FORMAT');
                utilsService.displayMessage('error', translatedMessage);
            }
        }

        function getIcon(status) {
            const statusesIcons = {
                proposed: 'time',
                accepted: 'ok',
                canceled: 'remove-circle',
                declined: 'ban-circle',
                invalid: 'remove-circle'
            };

            return statusesIcons[status];
        }

        function shouldShowAddNewDate() {
            $scope.$evalAsync(() => {
                $scope.showAddNewDate = !$scope.showAddNewDate;
            });
        }

        function isDateProposedByMe(installationDate) {
            return $scope.confirmationDates[installationDate].lastStatus === 'proposed' &&
                $scope.confirmationDates[installationDate].isProposedByMe === true;
        }

        function removeMyDate(installationDate) {
            const params = $.param({
                idOrder,
                idPackage,
                installationDate
            });

            $http({
                method: 'POST',
                data: params,
                url: 'orders/api/removeMyDate'
            }).then(displayMessage, utilsService.onHttpError);
        }

        function showHideAcceptDialog(confirmationDate) {
            checkIfDateAlreadyAccepted();
            $scope.isAcceptDialogVisible[confirmationDate] = !$scope.isAcceptDialogVisible[confirmationDate];

        }

        function showHideDeclineDialog(confirmationDate) {
            $scope.$evalAsync(() => {
                $scope.isDeclineDialogVisible[confirmationDate] = !$scope.isDeclineDialogVisible[confirmationDate];
            });
        }

        function showHideRemoveDialog(confirmationDate) {
            $scope.$evalAsync(() => {
                $scope.isRemoveDialogVisible[confirmationDate] = !$scope.isRemoveDialogVisible[confirmationDate];
            });
        }

        function userButtonAction(data) {
            if (data.userStatus && data.confirmationDate) {
                updateInstallationDate(data.confirmationDate, data.userStatus);
            }
        }

        function canUserAcceptOrDecline(confirmationDate, dateInfo, lastStatus) {
            let additionalCondition = false;
            if (dateInfo.lastStatus === 'proposed') {
                $scope.offsetClass = 'col-md-offset-1';
            } else {
                $scope.offsetClass = 'col-md-offset-3';
            }
            if (lastStatus === 'declined') {
                additionalCondition = dateInfo.lastStatus === 'canceled' && dateInfo.isProposedByMe;
            }
            return !$scope.isInstallationSchedulingDisabled() &&
                ((dateInfo.lastStatus === 'proposed' && !dateInfo.isProposedByMe) ||
                    (dateInfo.lastStatus === lastStatus && dateInfo.isProposedByMe) ||
                    additionalCondition);
        }

        function isRemoveBtnVisible(confirmationDate) {
            return !$scope.isInstallationSchedulingDisabled() && isDateProposedByMe(confirmationDate);
        }

        function uploadFile(file) {
            const idSupplier = $scope.installationCompany && $scope.installationCompany.idSupplier ? $scope.installationCompany.idSupplier : 0;
            Upload.upload({
                url: 'orders/api/uploadInstallationDocument',
                method: 'POST',
                file: file,
                data: {
                    idPackage,
                    idOrder,
                    idSupplier,
                    fileType: 'installationProtocol'
                }
            }).then(displayMessage, utilsService.onHttpError);
        }

        function showHideDialog(idDocument) {
            $scope.$evalAsync(() => {
                $scope.isDialogVisible[idDocument] = !$scope.isDialogVisible[idDocument];
            });
        }

        function showHideInstallationDialog(idInstallationCompany) {
            $scope.$evalAsync(() => {
                $scope.isInstallationDialogVisible[idInstallationCompany] = !$scope.isInstallationDialogVisible[idInstallationCompany];
            });
        }

        function removeInstallDocument(idDocument) {
            const params = $.param({
                idOrder,
                idPackage,
                idDocument
            });

            $http({
                method: 'POST',
                data: params,
                url: 'orders/api/removeOrderDocument'
            }).then(displayMessage, utilsService.onHttpError);
        }

        function activateChangeInstallation() {
            $scope.isChangeInstallationAvailable = !$scope.isChangeInstallationAvailable;
        }

        function showHideChangingInstallationDialog() {
            $scope.$evalAsync(() => {
                $scope.isChangingInstallationDialogVisible = !$scope.isChangingInstallationDialogVisible;
            });
        }

        function showDateDetails(installationDate) {
            installationDate.isInfoVisible = !installationDate.isInfoVisible;
        }
    }
})();
