define(['./user_picker.directive.html', 'jquery'], function (template, $)
{
    UserPicker.$inject = ['$timeout'];
    function UserPicker($timeout)
    {
        return {
            restrict: 'E',
            require: '^ngModel',
            templateUrl: template,
            scope: {
                ngModel: '=',
                control: '=',
                allowBlocked: '@'
            },
            link: link
        };

        function link(scope, iElement, iAttrs, ctrl)
        {
            scope.id = iAttrs.selectId + '-inner';
            ctrl.user_name = iAttrs.userName;

            var allow_unset = iAttrs.allowUnset == 1;

            // Get project ID if there is one to limit search results
            scope.project_id = iAttrs.projectId || 0;
            scope.project_rights = iAttrs.projectRights || 0;
            scope.project_param = '';

            if ((typeof(scope.project_id) !== 'undefined') &&
                (scope.project_id > 0))
            {
                scope.project_param = '?project_id=' + scope.project_id;
            }

            // Don't use the system user_picker_popup.php because we need to filter results to a projects team members if needed
            ctrl.UserPicker_InitSelect2 = function (element_id, project_id, project_rights, placeholder, allow_unset) {
                var el = jq_$(element_id);
                var page_size = 50;

                var e = el.select2({
                    placeholder: placeholder,
                    minimumInputLength: 3,
                    width: '100%',
                    allowClear: allow_unset,
                    ajax: {
                        url: "/api/projects/v2/projects/" + project_id + "/users",
                        dataType: 'json',
                        delay: 250,
                        data: function (params) {
                            var page = params.page || 1;
                            return {
                                name: params.term, // search term
                                limit: page_size,
                                offset: (page-1) * page_size,
                                fields: "fullname"
                            };
                        },
                        processResults: function (data, params) {
                            params.page = params.page || 1;
                            var list = data.data.map(function(elem){
                                return {
                                    id: elem.id,
                                    text: elem.fullname
                                }
                            });

                            if (!!scope.allowBlocked) {
                                list.push({id: 0, text: lmsg('projects.task.user_blocked')});
                            }

                            return {
                                results: list,
                                pagination: {
                                    more: data.pagination.next != null
                                }
                            };
                        }
                    }
                });
            };

            // Angular won't have populated the control/browse ids yet so wait until the current event is finished
            $timeout(function(id, text, allow_unset, scope){
                scope.initSelect2(id, text, allow_unset)
            }, 0, true, scope.id, lmsg('projects.picker.select_user'), allow_unset, scope);

            if (scope.ngModel !== undefined && scope.ngModel !== null && Array.isArray(scope.ngModel)) {
                scope.ngModel.map(function (user) {
                    $('#' + scope.id).append($('<option>').attr('value', user.id).attr('selected', 'selected').text(user.name));
                });
            }

            ctrl.UserPicker_InitSelect2(scope.id, scope.project_id, scope.project_rights, lmsg('projects.picker.select_user'), allow_unset);

            ctrl.$viewChangeListeners.push(function() {
                scope.$eval(iAttrs.ngChange);
            });

            scope.initSelect2 = function(id, text, allow_unset)
            {
                var select = $('#' + id);
                select.find('option').remove();

                // Add an entry for the current user if needed
                if (scope.ngModel !== undefined && scope.ngModel !== null && Array.isArray(scope.ngModel)) {
                    scope.ngModel.map(function (user) {
                        select.append($('<option>').attr('value', user.id).text(user.name).attr('selected', 'selected'));
                    });
                }

                select.on('change', function() {
                    var $el = angular.element(this);
                    var user_ids = $el.val();

                    // cast variables to int
                    user_ids = user_ids.map(function (user_id) {
                        return parseInt(user_id);
                    });

                    var user_id = user_ids.slice(-1)[0];
                    var name = user_id === '' ? '' : $el.find('option[value=' + user_id + ']').text();

                    scope.change(user_ids, name);
                });

                ctrl.UserPicker_InitSelect2(scope.id, scope.project_id, scope.project_rights, text, allow_unset);
            };

            /**
             * @param user_ids Array
             * @param name string
             */
            scope.change = function(user_ids, name)
            {
                if (!Array.isArray(user_ids))
                    user_ids = [];

                scope.user_name = name;
                ctrl.$setViewValue(user_ids);
                ctrl.$render();

                $timeout(function(user_ids) {
                    ctrl.$setViewValue(user_ids);
                    ctrl.$render();
                }, 0, true, user_ids);
            };

            scope.browse = function(event)
            {
                event.preventDefault();
                var project_params = '';
                if (scope.project_id > 0)
                    project_params = '&project_id=' + scope.project_id;
                var recwnd = window.open('/projects/user_picker_popup?input_dom_id=' + scope.id + project_params + '&multi=1','user_picker_wnd','width=800,height=450,scrollbars=yes,resizable=yes,hotkeys=no,maximize=no');
                recwnd.focus();
            };

            scope.internalControl = scope.control || {};
            scope.internalControl.reset = function(user_name)
            {
                // Rebind the model. This shouldn't be needed but it never gets updated once reset otherwise
                ctrl.$setViewValue(scope.ngModel);

                scope.initSelect2(scope.id, lmsg('projects.picker.select_user'), true);

                var select = $('#' + scope.id);
                select.find('option').remove();
            };
        }
    }

    return UserPicker;
});
