
import './UserManagement.html';
import '/imports/util/selectize/selectize.js'

let QUERY_LIMIT = 100;
let QUERY_LIMIT_INCREMENT = 100;
let PREFIX = "UserManagement";

Tracker.autorun(function() {
	Meteor.subscribe("users", Session.get(PREFIX + 'searchQuery'));
	Meteor.subscribe("roles");
});

Template.UserManagement.onCreated(function() {
	Session.set(PREFIX + "displayNewUser", false);
	Session.set(PREFIX + "queryLimit", QUERY_LIMIT);
});
Template.UserManagement.onRendered(function() {
	$(".tableContainer").mCustomScrollbar({
		scrollButtons: {enable:true},
		theme: "light-thick",
		scrollbarPosition: "outside",
		scrollEasing: "linear"
	});
});
Template.UserManagement.helpers({
	displayNewUser: function() {
		return Session.get(PREFIX + "displayNewUser");
	},
	users: function() {
		let skipCount = Session.get(PREFIX + 'skipCount') || 0;
		let query = Session.get(PREFIX + 'searchQuery');
		let dbQuery = [];
		
		if(query) {
			_.each(_.keys(query), function(key) {
				if(_.isFunction(query[key])) dbQuery.push({[key]: query[key]});  //dbQuery[key] = query[key]();
				else if(_.isObject(query[key])) dbQuery.push({[key]: query[key]});  //dbQuery[key] = query[key];  //Will look something like: {$in: [xxx,xxx,xxx]}
				else if(_.isNumber(query[key])) dbQuery.push({[key]: query[key]});  //dbQuery[key] = query[key];
				else {
					//dbQuery[key] = {$regex: query[key], $options: 'i'};
					let searchValue = query[key];
					let searches = searchValue && searchValue.length > 0 ? searchValue.split(/\s+/) : undefined;
					
					for(let search of searches) {
						dbQuery.push({[key]: {$regex: '\\b' + search, $options: 'i'}});
					}
				}
			})
		}
		
		if(!Session.get(PREFIX + "showHidden")) {
			//Ignore any hidden elements by showing those not hidden, or those without the hidden field.
			dbQuery.push({$or: [{hidden: false}, {hidden: {$exists:false}}]});
		}
		
		dbQuery = dbQuery.length > 0 ? {$and: dbQuery} : {};
		Session.set(PREFIX + 'userCount',  Meteor.collections.Users.find(dbQuery).count());  //Always get a full count.
		return Meteor.collections.Users.find(dbQuery, {limit: Session.get(PREFIX + "queryLimit"), skip: skipCount, sort: {username: 1}});
	},
	disableLoadMore: function() {
		return Session.get(PREFIX + 'userCount') - (Session.get(PREFIX + 'skipCount') || 0) - Session.get(PREFIX + "queryLimit") <= 0;
	}
});
Template.UserManagement.events({
	'click .loadMoreLink': function(event, template) {
		event.preventDefault();
		Session.set(PREFIX + 'queryLimit', Session.get(PREFIX + "queryLimit") + QUERY_LIMIT_INCREMENT);
	},
	'click .newUserButton': function(event, template) {
		if(template.$('.newUserButton').hasClass('active')) {
			Session.set(PREFIX + 'displayNewUser', false);
		}
		else {
			Session.set(PREFIX + 'displayNewUser', true);
			Session.set(PREFIX + "editedUser", undefined);  //Clear the edited user so that only one editor is open at a time.
		}
		template.$('.newUserButton').toggleClass('active');
	}
});

Template.User.onCreated(function() {
	this.edited = new ReactiveVar();
});
Template.User.events({
	"click .userEdit": function(event, template) {
		//template.edited.set(this);
		Session.set(PREFIX + "editedUser", this._id);
		Session.set(PREFIX + 'displayNewUser', false);  //Ensure the new measure editor is closed.
		template.parentTemplate().$('.newUserButton').removeClass('active');
	},
	"click .userRemove": function(event, template) {
		let _this = this;
		bootbox.confirm({
			message: "Delete the user?",
			buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
			callback: function(result) {
				if(result) {
					Meteor.call('deleteUser', _this._id, function(error, result) {
						if(error) {
							sAlert.error(error);
						}
						else {
							sAlert.success("User removed.");
						}
					});
				}
			}
		});
	}
});
Template.User.helpers({
	email: function() {
		return this.emails && this.emails.length > 0 ? this.emails[0].address : "";
	},
	editing: function() {
		let editedUser = Session.get(PREFIX + "editedUser");
		
		return editedUser == this._id;
	}
});

Template.UserEditor.helpers({
	email: function() {
		return this.emails && this.emails.length > 0 ? this.emails[0].address : "";
	},
	allRoles: function() {
		return Meteor.collections.UserRoles.find();
	},
	getRoleState: function(role) {
		let user = Template.parentData(1);
		
		return !user.isNew && user.roles.includes(role.name) ? "selected" : "";
	}
});
Template.UserEditor.events({
	"click .editorCancel": function(event, template) {
		Session.set(PREFIX + "editedUser", undefined);
		Session.set(PREFIX + 'displayNewUser', false);
		template.parentTemplate().$('.newUserButton').removeClass('active');
	},
	"click .editorApply": function(event, template) {
		let user = {};
		let roles = [];
		
		user.username = template.$('input[name="username"]').val();
		user.email = template.$('input[name="email"]').val();
		
		let roleSpans = template.$('.role.selected');
		for(let i = 0; i < roleSpans.length; i++) {
			roles.push($(roleSpans[i]).text());
		}
		
		user.roles = roles;
		
		if(Session.get(PREFIX + 'displayNewUser')) {
			Meteor.call('insertUser', user, function(error, result) {
				if(error) {
					sAlert.error(error);
				}
				else {
					sAlert.success("User created.");
					Session.set(PREFIX + 'displayNewUser', false);
					template.parentTemplate().$('.newUserButton').removeClass('active');
				}
			});
		}
		else {
			user._id = this._id;
			Meteor.call("updateUser", user, function(error, result) {
				if(error) sAlert.error(error);
				else {
					sAlert.success("User updated.");
					Session.set(PREFIX + "editedUser", undefined);
					template.parentTemplate().$('.newUserButton').removeClass('active');
				}
			});
		}
		
	},
	"click .role": function(event, template) {
		$(event.target).toggleClass("selected");
	}
});

Template.UserSearch.events({
	"keyup .searchInput": _.throttle(function(event, template) {
		let searchQuery = Session.get(PREFIX + 'searchQuery') || {};
		let searchFields = Session.get(PREFIX + 'searchFields') || {};
		let searchValue = template.$('.searchInput').val();
		
		if(searchValue) {
			if(this.number) searchValue = parseFloat(searchValue);
			
			if(this.collection) {
				let ids = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch();
				
				//Convert the ids to an array of ids instead of an array of objects containing an id.
				for(let i = 0; i < ids.length; i++) {ids[i] = ids[i]._id;}
				searchQuery[this.columnName] = {$in: ids};
				searchFields[this.columnName] = searchValue;
			}
			else {
				searchFields[this.columnName] = searchQuery[this.columnName] = searchValue;
			}
		}
		else {
			//Remove columns from the search query whose values are empty so we don't bother the database with them.
			delete searchQuery[this.columnName];
			delete searchFields[this.columnName];
		}
		
		Session.set(PREFIX + 'searchQuery', searchQuery);
		Session.set(PREFIX + 'skipCount', 0);  //Reset the paging of the results.
	}, 500)
});
Template.UserSearch.helpers({
	searchValue: function() {
		let searchFields = Session.get(PREFIX + 'searchFields');
		
		return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
	}
});