(function () {
    'use strict';

    angular
        .module('app')
        .controller('Home.UserViewController', HomeController)
        .controller('Home.AppViewController', AppController)
        .service('taskOperations', TaskOperations)
        .service('taskService', TaskService)
        .service('isTokenValid', isTokenValid)
        .controller('ModalInstanceCtrl', ModalInstanceCtrl)
        .controller('RemoveTaskCtrl', RemoveTaskCtrl)
        .controller('UpdateTaskCtrl', UpdateTaskCtrl)
        .controller('groupCtrl', function($scope) {
            $scope.group.$hideRows = true;
        });

    function configureDefaults(ngTableDefaults) {
        ngTableDefaults.params.count = 5;
        ngTableDefaults.settings.counts = [];
    }

    function isTokenValid($rootScope){
        var now = new Date().getTime() / 1000 | 0;
        return now > $rootScope.globals.currentUser.expiry;
    }

    function AppController(ngTableParams, $scope, taskService, growl){
        var vm = this;

        $scope.data = [];
        
        var promise = taskService.getTasksForAllUsers();
        promise.then(function(data){
            $scope.data = data;
            vm.allUserTableParams = new ngTableParams({
                page: 1, // show first page
                count: 50
            }, 
            {
                groupBy: 'userId',
                counts: [5, 10, 25, 50, 100],
                total: $scope.data.length,
                groupOptions: {
                    isExpanded: true
                },
                getData: function($defer, params) {
                    //$scope.data = $scope.allTasks.slice((params.page() - 1) * params.count(), params.page() * params.count());
                    //console.log($scope.data.length);
                    $defer.resolve($scope.data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
                }
            }
            );
        })
        .catch(function(err){
            console.log(err);
            growl.error(err.data + ' (' + err.status +' ' + err.statusText + ')');
        });
    }

    function HomeController(AuthenticationService, AlertService, NgTableParams, $scope, growl, taskOperations, taskService, isTokenValid, $uibModal, $log, $location, $rootScope) {
        var vm = this;

        $scope.tasks = [];
        $scope.task = {name: '', description: ''};
        $scope.animationsEnabled = true;

        $scope.username = $rootScope.globals.currentUser.username;
        
        if(taskService.isTokenValid()){
            var promise = taskService.getAll($rootScope.globals.currentUser.username);
            promise.then(function(tasks){
                $scope.tasks = tasks;
                vm.tableParams = new NgTableParams({
                        page: 1, // show first page
                        count: 5
                }, {
                        counts: [5, 10, 25, 50, 100],
                        total: $scope.tasks.length,
                        getData: function($defer, params) {
                            $scope.userData = $scope.tasks.slice((params.page() - 1) * params.count(), params.page() * params.count());
                            $defer.resolve($scope.userData);
                        }
                    }
                );
            })
            .catch(function(err){
                growl.error(err.data + ' (' + err.status +' ' + err.statusText + ')');
            });
        } else {
            AlertService.setError("Session expired. Please re-login again.");
            AuthenticationService.Logout();
            $location.path('/login');
        }

        $scope.toggleTask = function(task){
            vm.error = '';
            
            taskOperations.toggle(task);
            taskService.save(task, $scope.username)
                .then(function(){
                    vm.tableParams.total($scope.tasks.length);
                    vm.tableParams.reload();
                    growl.success('Task updation success!');
                })
                .catch(function(err){
                    taskOperations.toggle(task);
                    growl.error(err.data + ' (' + err.status +' ' + err.statusText + ')');
                    console.log(err);
                    $scope.task = {title: '', userId: '', description: ''};
                });
        };

        $scope.update = function(selectedTask){
            vm.error = '';
            $scope.task = angular.copy(selectedTask);
            var modalInstance = $uibModal.open({
                animation: $scope.animationsEnabled,
                templateUrl: 'myModalUpdate.html',
                backdrop: true,
                windowClass: 'modal',
                controller: 'UpdateTaskCtrl',
                scope: $scope,
                resolve: {
                    task : function(){
                        return $scope.task;
                    }
                }
            });
            
            modalInstance.result.then(function (editedTask){
                taskService
                    .save(editedTask, $rootScope.globals.currentUser.username)
                    .then(function(task){
                        var index = _.findWhere($scope.tasks,{id:task.id});
                        var b = _.indexOf($scope.tasks,index);
                        $scope.tasks.splice(b, 1, task);
                        $scope.task = {title: '', userId: '', description: ''};
                        vm.tableParams.total($scope.tasks.length);
                        vm.tableParams.reload();
                        growl.success('Task updation success!');
                    })
                    .catch(function(err){
                        growl.error(err.data + ' (' + err.status +' ' + err.statusText + ')');
                        console.log(err);
                        $scope.task = {title: '', userId: '', description: ''};
                    }); 
            }, function () {
                $log.info('Modal dismissed at: ' + new Date());
            });

        };

        $scope.remove = function(task){
            vm.error = '';
            var modalInstance = $uibModal.open({
                animation: $scope.animationsEnabled,
                templateUrl: 'myModalRemove.html',
                backdrop: true,
                windowClass: 'modal',
                controller: 'RemoveTaskCtrl',
                scope: $scope,
                resolve: {
                    removedTask : function(){
                        return task;
                    }
                }
            });

            modalInstance.result.then(function (deletedTask){
                taskService
                    .remove(deletedTask, $rootScope.globals.currentUser.username)
                    .then(function(task){
                        var index = _.findWhere($scope.tasks,{id:task.id});
                        var b = _.indexOf($scope.tasks,index);
                        $scope.tasks.splice(b,1);
                        vm.tableParams.total($scope.tasks.length);
                        vm.tableParams.reload();
                        growl.warning('Task deletion success!');
                    })
                    .catch(function(err){
                        growl.error(err.data + ' (' + err.status +' ' + err.statusText + ')');
                        console.log(err);
                    });
            }, function () {
                $log.info('Modal dismissed at: ' + new Date());
            });
        };

        $scope.open = function (){
            vm.error = '';
            $scope.task = {title: '', userId: '', description: ''};
            var modalInstance = $uibModal.open({
                animation: $scope.animationsEnabled,
                templateUrl: 'myModalContent.html',
                backdrop: true,
                windowClass: 'modal',
                controller: 'ModalInstanceCtrl',
                scope: $scope,
                resolve: {
                    selectedTask : function(){
                        return $scope.task;
                    }
                }
            });

            modalInstance.result.then(function (newTask) {
                var postTask = taskOperations.create(0, newTask.name, newTask.description, $rootScope.globals.currentUser.username);
                taskService
                    .addNew(postTask, $rootScope.globals.currentUser.username)
                    .then(function(task){
                        $scope.tasks.push(task);
                        $scope.task = {title: '', userId: '', description: ''};
                        vm.tableParams.total($scope.tasks.length);
                        vm.tableParams.reload();
                        growl.success('Task addition success!');
                    })
                    .catch(function(err){
                        console.log(err);
                        growl.error(err.data + ' (' + err.status +' ' + err.statusText + ')');
                        $scope.task = {title: '', userId: '', description: ''};
                    });
            }, function () {
                $log.info('Modal dismissed at: ' + new Date());
            });
        };

        $scope.logout = function (){
            AuthenticationService.Logout();
            location.reload();
        };
    }

    function UpdateTaskCtrl($scope, $uibModalInstance, task)
    {
        $scope.task = task;
        $scope.updateTask = function () {
            $uibModalInstance.close($scope.task);
        };

        $scope.cancel = function () {
            $scope.task = {title: '', userId: '', description: ''};
            $uibModalInstance.dismiss('cancel');
        };
    }

    function RemoveTaskCtrl($scope, $uibModalInstance, removedTask)
    {
        $scope.task = removedTask;
        $scope.deleteTask = function () {
            $uibModalInstance.close($scope.task);
        };

        $scope.cancel = function () {
            $scope.task = {title: '', userId: '', description: ''};
            $uibModalInstance.dismiss('cancel');
        };
    }

    function ModalInstanceCtrl($scope, $uibModalInstance, selectedTask){
        
        $scope.task = selectedTask;
        $scope.submitTask = function () {
            $uibModalInstance.close($scope.task);
        };

        $scope.cancel = function () {
            $scope.task = {title: '', userId: '', description: ''};
            $uibModalInstance.dismiss('cancel');
        };
    }

    function TaskOperations(){
        this.toggle = function(task){
            return task.closed = !task.closed;
        };

        this.create = function(id, taskName, taskDescription, username){
            return {
                id : id,
                userId : username,
                title: taskName,
                description: taskDescription,
                closed : false,
                createdAt : new Date()
            };
        };
    }
    
    function TaskService($http, $q, $rootScope){
        this.getAll = function(userId){
            return $http
                .get("/services/TaskRepository/ws/sample/tasks/" + userId)
                .then(function(response){
                    return response.data;
                });
        };

        this.getTasksForAllUsers = function(){
            return $http
                .get("/services/TaskDashboard/ws/resource/getresource")
                .then(function(response){
                    return response.data;
                });
        };

        this.addNew = function(newTask, userId){
            return $http
                .post("/services/TaskRepository/ws/sample/tasks/" + userId, newTask)
                .then(function(response){
                    return response.data;
                });
        };

        this.save = function(task, userId){
            return $http
                .put("/services/TaskRepository/ws/sample/tasks/" + userId + "/task/" + task.id, task)
                .then(function(response){
                    return response.data;
                });
        };
        
        this.remove = function(task, userId){
            return $http
                .delete("/services/TaskRepository/ws/sample/tasks/" + userId + "/task/" + task.id)
                .then(function(response){
                    return task;
                }); 
        };

        this.isTokenValid = function(){
            var now = new Date().getTime() / 1000 | 0;
            return now < $rootScope.globals.currentUser.expiry;
        };
    }
    
})();
