(function()
{
    var moduleName = 'taskListApp';

    var instance = new TaskListService();

    var Url = require('url-parse');

    angular.module(moduleName)
        .service('tasklistService', ['$http', 'tasklistPreloadFactory', function($http, taskListPreloadFactory) {
            instance.setInjectables($http, taskListPreloadFactory);
            return instance;
        }]);

    function TaskListService()
    {
        var service = this;

        service.$http = undefined;

        service.due_date_counts = {overdue:0, today:0, tomorrow:0, later:0, no_due_date:0};

        service.changeCallbacks = [];
        service.onChange = function(callable)
        {
            service.changeCallbacks.push(callable);
        }

        service.changePage = function (new_page_number) {

            if (new_page_number != service.currentPage) {
                service.currentPage = new_page_number;
                service.getResultsPage();
            }
        }

        // Load new task list data, using the current filters
        service.getResultsPage = function(suppress_history)
        {
            var query_params = {
                'task_filter': service.currentTaskFilter,
                'status_filter': service.currentStatusFilter,
            }

            if (service.searchTerms.length > 0)
                query_params.search = service.searchTerms;

            if (service.currentPage > 1)
                query_params.page = service.currentPage;

            // for multiple assignees add users as a array to the GET request
            if (Array.isArray(service.userFilter) && service.userFilter.length > 0)
            {
                service.userFilter.forEach(function (user, index) {
                    query_params['user_filter[' + index + ']'] = user;
                });
            }

            if (suppress_history !== true) {
                var url_history = new Url('tasks', {}, true);
                url_history.set('query', query_params);

                window.history.pushState({}, '', url_history.href);
            }

            var url = new Url('/projects/tasks', {}, true);
            query_params.format = 'json';
            url.set('query', query_params);

            service.$http.get(url.href)
                .then(function(result) {
                    service.task_filters = result.data.task_filter_count;
                    service.status_filters = result.data.status_filter_count;

                    for (var i = 0; i < service.changeCallbacks.length; i++)
                    {
                        service.changeCallbacks[i](result.data.tasks, result.data.task_count, result.data.tasks_per_page, result.data.current_page);
                    }

                    // This is needed due to a conflict between Angular and select2. When choosing a user via the 'browse' popup window (using $.select2('data', ...)) it correctly
                    // updates the Angular model which triggers this AJAX request but does not display the user name. So it needs to be a applied a second time post-render.
                    // Update. It also has to run after the current $digest or $apply call finishes so applying a small delay before it is called.
                    if (result.data.filtered_user_ids !== null)
                        setTimeout(function(id, name){window.UserPicker_SetUser('user_filter', id, name);}, 50, result.data.filtered_user_ids, result.data.user_filter_name);
                }
            );
        };

        service.setSearch = function(search)
        {
            service.searchTerms = search;
        }

        service.setUser = function(user_id)
        {
            service.userFilter = user_id;
        }

        service.setInjectables = function($http, factory)
        {
            service.$http = $http;

            // Set up filter vars and highlight the right one
            service.tasks = factory.tasks;
            service.task_count = factory.task_count;
            service.currentPage = factory.current_page;
            service.tasks_per_page = factory.tasks_per_page;
            service.task_filters = factory.task_filters;
            service.status_filters = factory.status_filters;
            service.currentTaskFilter = factory.current_task_filter;
            service.currentStatusFilter = factory.current_status_filter;
            service.searchTerms = factory.searchTerms;
            service.userFilter = factory.initial_user_filter;
            service.duration_units = factory.duration_units;
        }
    }
}());
