(function () {
    global.dashModule
        .controller('createDashboardCtrl', ['$scope', '$http', '$', '$translate', 'utilsService', createDashboardCtrl])
        .directive('createDashboard', [createDashboardDirective]);

    function createDashboardDirective() {
        return {
            restrict: 'E',
            templateUrl: 'dashboards/html/createDashboardTemplate'
        };
    }

    function createDashboardCtrl($scope, $http, $, $translate, utilsService) {
        const visibilityObjects = {
            'public': {
                icon: 'open',
                value: 'public'
            },
            'private': {
                icon: 'close',
                value: 'private'
            }
        };
        const ID_BROKER_TYPE = '1';

        $scope.initCreate = initCreate;
        $scope.getGadgets = getGadgets;
        $scope.showHideGadgets = showHideGadgets;
        $scope.addGadget = addGadget;
        $scope.removeGadget = removeGadget;
        $scope.gadgetDragStart = gadgetDragStart;
        $scope.gadgetDragStop = gadgetDragStop;
        $scope.gadgetDropped = gadgetDropped;
        $scope.createDashboard = createDashboard;
        $scope.changeVisibility = changeVisibility;
        $scope.getButtonTranslationKey = getButtonTranslationKey;
        $scope.isPublic = isPublic;
        $scope.getUserTypes = getUserTypes;
        $scope.canChangeVisibility = canChangeVisibility;
        $scope.gadgets = [];
        $scope.viewGadgets = false;
        $scope.selectedGadgets = [];
        $scope.dashboardName = '';
        $scope.visibility = visibilityObjects.private;
        $scope.idDashboard = 0;
        $scope.userTypes = [];
        $scope.selectedUserType = 0;

        function initCreate() {
            $scope.idDashboard = parseInt(global.getParameterByName('idDashboard')) || 0;

            if ($scope.idDashboard !== 0) {
                getDashboardInfo();
            } else {
                $scope.selectedGadgets = [];
                $scope.dashboardName = '';
                $scope.visibility = visibilityObjects.private;
                getGadgets();
            }
        }

        function getGadgets() {
            const params = $.param({
                idDashboard: $scope.idDashboard,
                selectedUserType: $scope.visibility.value === 'public' ? $scope.selectedUserType : 0
            });
            $http({
                method: 'POST',
                url: 'dashboards/api/getAllGadgets',
                data: params
            }).then(setGadgets, utilsService.onHttpError);
        }

        function setGadgets(response) {
            $scope.selectedGadgets = [];
            if (response.data && response.data.length) {
                $scope.gadgets = response.data;
                $scope.gadgets.forEach((gadget) => {
                    gadget.isSelected = parseInt(gadget.isSelected) === 1 ? true : false;
                    if (gadget.isSelected) {
                        addGadget(gadget);
                    }
                });
            } else {
                $scope.gadgets = [];
            }
        }

        function getDashboardInfo() {
            const params = $.param({
                idDashboard: $scope.idDashboard
            });
            $http({
                method: 'POST',
                url: 'dashboards/api/getDashboardInfo',
                data: params
            }).then(setDashboardInfo, utilsService.onHttpError);
        }

        function setDashboardInfo(response) {
            if (response.data && response.data.dashboardInfo) {
                $scope.dashboardName = response.data.dashboardInfo.name;
                $scope.visibility = visibilityObjects[response.data.dashboardInfo.visibility];
                $scope.selectedUserType = response.data.dashboardInfo.idUserType;
                getGadgets();
                getUserTypes();
            } else if (response.data && response.data.messages) {
                let translatedMessage = $translate.instant('dashboards.messages.' + response.data.messages.message);
                utilsService.displayMessage(response.data.messages.code, translatedMessage);
            }
        }

        function showHideGadgets() {
            $scope.viewGadgets = !$scope.viewGadgets;
        }

        function addGadget(gadget) {
            if ($scope.selectedGadgets.indexOf(gadget) === -1) {
                $scope.selectedGadgets.push(gadget);
                gadget.isSelected = true;
                gadget.position = $scope.selectedGadgets.length;
            }
            $scope.viewGadgets = false;
        }

        function removeGadget(gadget) {
            const posOfGadget = $scope.selectedGadgets.indexOf(gadget);
            if (posOfGadget !== -1) {
                $scope.selectedGadgets.splice(posOfGadget, 1);
                gadget.isSelected = false;
            }
        }

        function gadgetDragStart(event, ui) {
            $(ui.helper).css({
                'z-index': 1001
            });
            $('.drop-zone').show();
        }

        function gadgetDragStop() {
            $('.drop-zone').hide();
        }

        function getGadgetById(idGadget) {
            return $scope.selectedGadgets.find((element) => {
                return element.idGadget === idGadget;
            });
        }

        function reorderGadgets(idGadgetToReposition, idGadgetToReplace) {
            const gadgetToReposition = getGadgetById(idGadgetToReposition);
            const gadgetToReplace = getGadgetById(idGadgetToReplace);
            const oldPosition = gadgetToReposition.position;
            gadgetToReposition.position = gadgetToReplace.position;
            gadgetToReplace.position = oldPosition;
            $scope.selectedGadgets.sort((a, b) => {
                return utilsService.sortByAtribute(a, b, 'position');
            });
        }

        function gadgetDropped(event, ui, currentGadget) {
            reorderGadgets(ui.helper.attr('idGadget'), currentGadget.idGadget);
        }

        function createDashboard() {
            const params = $.param({
                idDashboard: $scope.idDashboard,
                name: $scope.dashboardName,
                visibility: $scope.visibility.value,
                selectedUserType: $scope.selectedUserType,
                selectedGadgets: JSON.stringify($scope.selectedGadgets)
            });

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

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

        function changeVisibility() {
            if ($scope.visibility.value === 'private') {
                $scope.visibility = visibilityObjects.public;
                if ($scope.userTypes.length === 0) {
                    getUserTypes();
                }
            } else {
                if ($scope.selectedUserType !== ID_BROKER_TYPE) {
                    $scope.selectedGadgets = [];
                }
                $scope.visibility = visibilityObjects.private;
            }
        }

        function getButtonTranslationKey() {
            return $scope.idDashboard === 0 ? 'CREATE' : 'UPDATE';
        }

        function isPublic() {
            return $scope.visibility.value === 'public' && $scope.idDashboard === 0;
        }

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

        function setUserTypes(response) {
            if (response.data.length > 0) {
                $scope.userTypes = response.data;
                if ($scope.selectedUserType === 0) {
                    $scope.selectedUserType = response.data[0].id;
                }
            }
        }

        function canChangeVisibility(){
            return $scope.idDashboard === 0 || ($scope.idDashboard !== 0 && $scope.selectedUserType === ID_BROKER_TYPE);
        }
    }
})();
