(function () {
    global.dashModule
        .controller('setDeliveryDatesCtrl', ['$scope', '$', '$http', '$translate', 'utilsService', 'ordersUtilsService', setDeliveryDatesCtrl])
        .directive('setDeliveryDates', [setDeliveryDatesDirective]);

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

    function setDeliveryDatesCtrl($scope, $, $http, $translate, utilsService, ordersUtilsService) {
        let areEstimatedDatesSet = false;
        let areConfirmedDatesSet = false;
        const stepIdsForDeliveryDates = {
            firstStepEnabled: 5,
            lastStepEnabled: 6
        };
        $scope.isDatePickerOpen = {
            estimatedDate: {},
            confirmedDate: {}
        };
        const idOrder = global.getParameterByName('idOrder');
        const process = $scope.$parent.process;
        const idPackage = process.idPackage;
        const idProcess = process.idProcess;
        const stepInfo = {
            idOrder,
            idPackage,
            idProcess
        };
        $scope.idPackage = idPackage;
        $scope.getEstimationsAndEarliestInstallDate = getEstimationsAndEarliestInstallDate;
        $scope.updateSupplierEstimation = updateSupplierEstimation;
        $scope.getEstimationIcon = getEstimationIcon;
        $scope.getEstimatedOrConfirmedMaxDate = getEstimatedOrConfirmedMaxDate;
        $scope.updateTracking = updateTracking;
        $scope.addTracking = addTracking;
        $scope.supplierEstimations = [];
        $scope.shouldShowAddNewTracking = shouldShowAddNewTracking;
        $scope.showAddNewTracking = {};
        $scope.removeTracking = removeTracking;
        $scope.isRemoveDialogVisible = {};
        $scope.showHideRemoveDialog = showHideRemoveDialog;
        $scope.isTrackingEmpty = isTrackingEmpty;
        $scope.removeSupplierEstimation = removeSupplierEstimation;
        $scope.areProductsInOrder = true;
        $scope.openDatePicker = openDatePicker;
        $scope.isDateEditable = isDateEditable;
        $scope.isRemoveDatesDialogVisible = {
            'estimated': {},
            'confirmed': {}
        };
        $scope.showHideRemoveDatesDialog = showHideRemoveDatesDialog;
        $scope.earliestInstallationDate = () => {
            return ordersUtilsService.getEarliestInstallationDate(idOrder);
        };
        $scope.isSetDeliveryDatesDisabled = () => {
            return ordersUtilsService.isComponentDisabled(idOrder, 'setDeliveryDates');
        };

        function getEstimationsAndEarliestInstallDate() {
            getSupplierEstimations();
            ordersUtilsService.checkIfIsNextStepWanted(idOrder, 'setDeliveryDates', stepIdsForDeliveryDates);
            ordersUtilsService.getEarliestInstallationDateFromDb(idOrder, idPackage);
            utilsService.registerFunction('getSupplierEstimations', getSupplierEstimations);
        }

        function getSupplierEstimations(onInit = false) {
            const params = $.param({
                idOrder
            });

            $http({
                method: 'POST',
                data: params,
                url: 'orders/api/getSupplierEstimations'
            }).then((response) => {
                setSuppliersEstimations(response, onInit);
            }, utilsService.onHttpError);
        }

        function setSuppliersEstimations(response, onInit = false) {
            areEstimatedDatesSet = false;
            areConfirmedDatesSet = false;

            if (response.data) {
                $scope.supplierEstimations = response.data;
                if ($scope.supplierEstimations.length === 0) {
                    $scope.areProductsInOrder = false;
                }

                $scope.supplierEstimations.forEach(supplierEstimation => {
                    $scope.showAddNewTracking[supplierEstimation.idSupplier] = !supplierEstimation.trackings.length;
                });
            }

            if (!onInit) {
                areEstimatedDatesSet = checkEstimatedDateSet($scope.supplierEstimations);
                areConfirmedDatesSet = checkConfirmedDateSet($scope.supplierEstimations);

                if (areConfirmedDatesSet) {
                    const maxConfDate = getEstimatedOrConfirmedMaxDate('confirmedDate');
                    ordersUtilsService.setMaximumDeliveryDate(idOrder, 0, maxConfDate);
                } else if (areEstimatedDatesSet) {
                    const maxEstimatedDate = getEstimatedOrConfirmedMaxDate('estimatedDate');
                    const maxConfDate = getEstimatedOrConfirmedMaxDate('confirmedDate');
                    const maxDate = maxConfDate !== '-' ? maxConfDate > maxEstimatedDate ? maxConfDate : maxEstimatedDate : maxEstimatedDate;
                    ordersUtilsService.setMaximumDeliveryDate(idOrder, 0, maxDate);
                }
            }

            utilsService.executeRegisteredFunction('isNextBtnDisabled', stepInfo);
        }

        function checkEstimatedDateSet(supplierEstimations) {
            return supplierEstimations.every(supplierEstimation => {
                return supplierEstimation.estimatedDate !== null;
            });
        }

        function checkConfirmedDateSet(supplierEstimations) {
            return supplierEstimations.every(supplierEstimation => {
                return supplierEstimation.confirmedDate !== null;
            });
        }

        function addTracking(idSupplier, trackingNumber, trackingUrl) {
            const params = $.param({
                idOrder,
                idSupplier,
                trackingNumber,
                trackingUrl
            });

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

        function updateTracking(trackingInfo) {
            const params = $.param({
                idTracking: trackingInfo.idTracking,
                trackingNumber: trackingInfo.trackingNumber,
                trackingUrl: trackingInfo.trackingUrl
            });

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

        function removeSupplierEstimation(fctParams) {
            const params = $.param({
                idOrder,
                type: fctParams.type,
                idSupplier: fctParams.idSupplier
            });

            if(areEstimatedDatesSet) {
                if(!areConfirmedDatesSet && fctParams.type === 'estimation') {
                    ordersUtilsService.setMaximumDeliveryDate(idOrder, 0, 'remove');
                }
            } else if(!areEstimatedDatesSet && areConfirmedDatesSet){
                ordersUtilsService.setMaximumDeliveryDate(idOrder, 0, 'remove');
            } else if(areEstimatedDatesSet || areConfirmedDatesSet) {
                const maxEstimatedDate = getEstimatedOrConfirmedMaxDate('estimatedDate');
                const maxConfDate = getEstimatedOrConfirmedMaxDate('confirmedDate');
                const maxDate = maxConfDate !== '-' ? maxConfDate > maxEstimatedDate ? maxConfDate : maxEstimatedDate : maxEstimatedDate;
                ordersUtilsService.setMaximumDeliveryDate(idOrder, 0, maxDate);
            }

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

        function updateSupplierEstimation(date, supplierEstimation) {
            if (Date.parse(date)) {
                const params = $.param({
                    idOrder,
                    idSupplier: supplierEstimation.idSupplier,
                    estimatedDate: supplierEstimation.estimatedDate,
                    confirmedDate: supplierEstimation.confirmedDate
                });

                if (supplierEstimation.confirmedDate && areEstimatedDatesSet) {
                    const maxEstimatedDate = getEstimatedOrConfirmedMaxDate('estimatedDate');
                    const maxConfDate = getEstimatedOrConfirmedMaxDate('confirmedDate');
                    let maxDate = maxEstimatedDate;
                    if(maxConfDate !== '-') {
                        if(maxConfDate > maxEstimatedDate) {
                            maxDate = maxConfDate;
                        }
                    }
                    ordersUtilsService.setMaximumDeliveryDate(idOrder, 0, maxDate);
                }

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

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

                    if (response.data.messages[0].code === 'success') {
                        getSupplierEstimations();
                        if ('idProduct' in response.data) {
                            $scope.isDatePickerOpen['estimatedDate'][response.data.idProduct] = false;
                            $scope.isDatePickerOpen['confirmedDate'][response.data.idProduct] = false;
                        }
                    }
                });
            }
        }

        function getEstimationIcon(confirmedDate) {
            return confirmedDate ? 'glyphicon-ok' : 'glyphicon-time';
        }

        function getEstimatedOrConfirmedMaxDate(key) {
            let maxDate = '2000-01-01';
            let d1;
            let d2;

            const maxTempDate = $scope.supplierEstimations.length > 0 ?
                $scope.supplierEstimations.reduce((a, b) => {
                    d1 = new Date(a[key]);
                    d2 = new Date(b[key]);

                    return d1 < d2 ? b : a;
                }) : maxDate;

            d1 = new Date(maxTempDate[key]);
            d2 = new Date(maxDate);
            maxDate = d1 > d2 ? maxTempDate[key] : maxDate;

            return maxDate !== '2000-01-01' ? maxDate : '-';
        }

        function shouldShowAddNewTracking(idSupplier) {
            $scope.$evalAsync(() => {
                $scope.showAddNewTracking[idSupplier] = !$scope.showAddNewTracking[idSupplier];
            });
        }

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

        function removeTracking(trackingInfo) {
            const params = $.param({
                idTracking: trackingInfo.idTracking
            });

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

        function isTrackingEmpty(trackingData) {
            return trackingData.length === 0;
        }

        function openDatePicker(dateType, idSupplier) {
            if (!(idSupplier in $scope.isDatePickerOpen[dateType])) {
                $scope.isDatePickerOpen[dateType][idSupplier] = false;
            }
            $scope.isDatePickerOpen[dateType][idSupplier] = !$scope.isDatePickerOpen[dateType][idSupplier];
        }

        function isDateEditable(dateType, supplierEstimation) {
            return $scope.isDatePickerOpen[dateType][supplierEstimation.idSupplier] || !supplierEstimation[dateType];
        }

        function showHideRemoveDatesDialog(type, supplierEstimation) {
            $scope.$evalAsync(() => {
                $scope.isRemoveDatesDialogVisible[type][supplierEstimation.idSupplier] = !$scope.isRemoveDatesDialogVisible[type][supplierEstimation.idSupplier];
            });
        }
    }
})();
