"use strict";

var usersController = {};

var async = require('async'),
	validator = require('validator'),

	user = require('../user'),
	meta = require('../meta'),
	categories = require('../categories'),
	topics = require('../topics'),
	pagination = require('../pagination'),
	plugins = require('../plugins'),
	db = require('../database'),
	helpers = require('./helpers');

usersController.getOnlineUsers = function(req, res, next) {
	var	websockets = require('../socket.io');

	async.parallel({
		users: function(next) {
			user.getUsersFromSet('users:online', req.uid, 0, 49, next);
		},
		count: function(next) {
			var now = Date.now();
			db.sortedSetCount('users:online', now - 300000, now, next);
		},
		isAdministrator: function(next) {
			user.isAdministrator(req.uid, next);
		}
	}, function(err, results) {
		if (err) {
			return next(err);
		}

		if (!results.isAdministrator) {
			results.users = results.users.filter(function(user) {
				return user && user.status !== 'offline';
			});
		}

		var userData = {
			'users:online': true,
			search_display: 'hidden',
			loadmore_display: results.count > 50 ? 'block' : 'hide',
			users: results.users,
			anonymousUserCount: websockets.getOnlineAnonCount()
		};

		render(req, res, userData, next);
	});
};

usersController.getUsersSortedByPosts = function(req, res, next) {
	usersController.getUsers('users:postcount', 0, 49, req, res, next);
};

usersController.getUsersSortedByReputation = function(req, res, next) {
	usersController.getUsers('users:reputation', 0, 49, req, res, next);
};

usersController.getUsersSortedByJoinDate = function(req, res, next) {
	usersController.getUsers('users:joindate', 0, 49, req, res, next);
};

usersController.getUsers = function(set, start, stop, req, res, next) {
	usersController.getUsersAndCount(set, req.uid, start, stop, function(err, data) {
		if (err) {
			return next(err);
		}
		var pageCount = Math.ceil(data.count / (parseInt(meta.config.userSearchResultsPerPage, 10) || 20));
		var userData = {
			search_display: 'hidden',
			loadmore_display: data.count > (stop - start + 1) ? 'block' : 'hide',
			users: data.users,
			pagination: pagination.create(1, pageCount)
		};
		userData[set] = true;
		render(req, res, userData, next);
	});
};

usersController.getUsersAndCount = function(set, uid, start, stop, callback) {
	async.parallel({
		users: function(next) {
			user.getUsersFromSet(set, uid, start, stop, next);
		},
		count: function(next) {
			db.getObjectField('global', 'userCount', next);
		}
	}, function(err, results) {
		if (err) {
			return callback(err);
		}
		results.users = results.users.filter(function(user) {
			return user && parseInt(user.uid, 10);
		});

		callback(null, results);
	});
};

usersController.getUsersForSearch = function(req, res, next) {
	if (!req.uid && parseInt(meta.config.allowGuestUserSearching, 10) !== 1) {
		return helpers.notAllowed(req, res);
	}
	var resultsPerPage = parseInt(meta.config.userSearchResultsPerPage, 10) || 20;

	usersController.getUsersAndCount('users:joindate', req.uid, 0, resultsPerPage - 1, function(err, data) {
		if (err) {
			return next(err);
		}

		var userData = {
			search_display: 'block',
			loadmore_display: 'hidden',
			users: data.users
		};

		render(req, res, userData, next);
	});
};

usersController.getMap = function(req, res, next) {
	var socketIO = require('../socket.io');
	var rooms = require('../socket.io/rooms');

	var roomNames = ['user_list', 'categories', 'unread_topics', 'recent_topics', 'popular_topics', 'tags'];
	var links = {
		user_list: '/users',
		categories: '/categories',
		unread_topics: '/unread',
		recent_topics: '/recent',
		popular_topics: '/popular',
		tags: '/tags'
	};

	var keys = Object.keys(rooms.roomClients());

	keys = keys.filter(function(key) {
		return key.startsWith('topic_') || key.startsWith('category_');
	});

	roomNames = roomNames.concat(keys);

	async.map(roomNames, function(roomName, next) {
		socketIO.getUsersInRoom(0, roomName, 0, 39, function(err, data) {
			if (err) {
				return next(err);
			}

			if (roomName.startsWith('category_')) {
				var cid = roomName.split('_')[1];
				categories.getCategoryFields(cid, ['slug', 'name'], function(err, categoryData) {
					if (err) {
						return next(err);
					}
					data.room = validator.escape(categoryData.name);
					data.link = '/category/' + categoryData.slug;
					next(null, data);
				});
			} else if (roomName.startsWith('topic_')) {
				var tid = roomName.split('_')[1];
				topics.getTopicFields(tid, ['slug', 'title'], function(err, topicData) {
					if (err) {
						return next(err);
					}
					data.room = validator.escape(topicData.title);
					data.link = '/topic/' + topicData.slug;
					next(null, data);
				});
			} else {
				next(null, data);
			}
		});
	}, function(err, data) {
		data.sort(function(a, b) {
			return b.total - a.total;
		});

		data.forEach(function(room) {
			if (!room.link) {
				room.link = links[room.room];
			}
		});

		res.render('usersMap', {rooms: data});
	});
};

function render(req, res, data, next) {
	plugins.fireHook('filter:users.build', {req: req, res: res, templateData: data}, function(err, data) {
		if (err) {
			return next(err);
		}
		data.templateData.inviteOnly = meta.config.registrationType === 'invite-only';
		res.render('users', data.templateData);
	});
}



module.exports = usersController;
