/* jslint node: true */
'use strict';

var MenuModule			= require('../core/menu_module.js').MenuModule;
var userDb				= require('../core/database.js').dbs.user;
var ViewController		= require('../core/view_controller.js').ViewController;
var TextView			= require('../core/text_view.js').TextView;
var getUserLoginHistory	= require('../core/stats.js').getUserLoginHistory;

var util				= require('util');
var moment				= require('moment');
var async				= require('async');
var assert				= require('assert');
var _					= require('lodash');

exports.moduleInfo = {
	name		: 'Last Callers',
	desc		: 'Last callers to the system',
	author		: 'NuSkooler',
	packageName	: 'codes.l33t.enigma.lastcallers'	//	:TODO: concept idea for mods
};

exports.getModule	= LastCallersModule;

//	:TODO:
//	*	config.evenRowSGR (optional)

function LastCallersModule(options) {
	MenuModule.call(this, options);

	var self		= this;
	this.menuConfig	= options.menuConfig;

	this.rows			= 10;
	
	if(_.isObject(this.menuConfig.config)) {
		if(_.isNumber(this.menuConfig.config.rows)) {
			this.rows = Math.max(1, this.menuConfig.config.rows);
		}
		if(_.isString(this.menuConfig.config.dateTimeFormat)) {
			this.dateTimeFormat = this.menuConfig.config.dateTimeFormat;
		}
	}
}

util.inherits(LastCallersModule, MenuModule);

LastCallersModule.prototype.enter = function(client) {
	LastCallersModule.super_.prototype.enter.call(this, client);

	//	we need the client to init this for theming
	if(!_.isString(this.dateTimeFormat)) {
		this.dateTimeFormat = this.client.currentTheme.helpers.getDateFormat('short') + ' ' +
			this.client.currentTheme.helpers.getTimeFormat('short');
	}
};

LastCallersModule.prototype.mciReady = function(mciData, cb) {
	var self	= this;
	var vc		= self.viewControllers.lastCallers = new ViewController( { client : self.client } );
	var loginHistory;

	async.series(
		[
			function callParentMciReady(callback) {
				LastCallersModule.super_.prototype.mciReady.call(this, mciData, function parentMciReady(err) {
					callback(err);
				});
			},
			function loadFromConfig(callback) {
				var loadOpts = {
					callingMenu	: self,
					mciMap		: mciData.menu,
					noInput		: true,
				};

				vc.loadFromMenuConfig(loadOpts, function startingViewReady(err) {
					callback(err);
				});
			},
			function fetchHistory(callback) {
				getUserLoginHistory(self.rows, function historyRetrieved(err, lh) {
					loginHistory = lh;
					callback(err);
				});
			},
			function fetchUserProperties(callback) {
				async.each(loginHistory, function entry(histEntry, next) {
					userDb.each(
						'SELECT prop_name, prop_value '	+ 
						'FROM user_property '			+
						'WHERE user_id=? AND (prop_name="location" OR prop_name="affiliation");',
						[ histEntry.userId ],
						function propRow(err, propEntry) {
							histEntry[propEntry.prop_name] = propEntry.prop_value;
						},
						function complete(err) {
							next();
						}
					);
				}, function complete(err) {
					callback(err);
				});
			},
			function createAndPopulateViews(callback) {
				//
				//	TL1 = who
				//	TL2 = location
				//	TL3 = affiliation
				//	TL4 = when
				//
				//	These form the order/layout for a row. Additional rows
				//	will use them as a template.
				//
				var views = {
					who			: vc.getView(1),
					location	: vc.getView(2),
					affils		: vc.getView(3),
					when		: vc.getView(4),
				};

				var row = views.who.position.row;

				var nextId = 5;

				function addView(templateView, text) {
					//	:TODO: Is there a better way to clone this when dealing with instances?
					var v = new TextView( {
						client			: self.client,
						id				: nextId++,
						position		: { row : row, col : templateView.position.col },
						ansiSGR			: templateView.ansiSGR,
						textStyle		: templateView.textStyle,
						textOverflow	: templateView.textOverflow,
						dimens			: templateView.dimens,
						resizable		: templateView.resizable,
					} );

					v.id			= nextId++;
					v.position.row	= row;

					v.setPropertyValue('text', text);
					vc.addView(v);
				};

				loginHistory.forEach(function entry(histEntry) {
					if(row === views.who.position.row) {
						views.who.setText(histEntry.userName);
						views.location.setText(histEntry.location);
						views.affils.setText(histEntry.affiliation);
						views.when.setText(moment(histEntry.timestamp).format(self.dateTimeFormat));
					} else {
						addView(views.who, histEntry.userName);
						addView(views.location, histEntry.location);
						addView(views.affils, histEntry.affiliation);
						addView(views.when, moment(histEntry.timestamp).format(self.dateTimeFormat));
					}

					row++;
				});

				callback(null);
			}
		],
		function complete(err) {
			if(err) {
				self.client.log.error(err);
			}
			cb(err);
		}
	);
};