using System;
using System.Data;
using System.Configuration;
using ASPNET.StarterKit.TimeTracker.DataAccessLayer;

namespace ASPNET.StarterKit.TimeTracker.BusinessLogicLayer
{
	//****************************************************************************
	//
	// TTUser Class
	//
	// The TTUser class represents a Time Tracker user, including their unique
	// userID and UserName.  Custom role information retrieved from the database
	// is also stored in the TTUser class.
	//
	//****************************************************************************

	public class TTUser
	{
		public const string UserRoleNone = "0";
		public const string UserRoleAdministrator = "1";
		public const string UserRoleProjectManager = "2";
		public const string UserRoleConsultant = "3";
		public const string UserRoleAdminPMgr = UserRoleAdministrator + "," + UserRoleProjectManager;
		public const string UserRolePMgrConsultant = UserRoleProjectManager + "," + UserRoleConsultant;

		private string  _displayName = string.Empty;
		private string	_firstName = string.Empty;
		private string	_lastName = string.Empty;
		private string  _password = String.Empty;
		private string	_role = UserRoleNone;
		private string	_roleName;
		private int		_userID;
		private string	_userName;		

		public TTUser()
		{
		}

		public TTUser(string UserName)
		{
			_userName = UserName;
		}

		public TTUser(int UserID, string UserName, string Name, string Role)
		{
			_userID = UserID;
			_userName = UserName;
			_displayName = Name;
			_role = Role;
		}

		public string DisplayName
		{
			get { return _displayName; }
			set { _displayName = value; }
		}

		public string FirstName
		{
			get { return _firstName; }
			set { _firstName = value; }
		}
		public string LastName
		{
			get { return _lastName; }
			set { _lastName = value; }
		}

		public string Name
		{
			get { return _displayName; }
			set { _displayName = value; }
		}

		public string Password
		{
			get { return _password; }
			set { _password = value; }
		}

		public string Role
		{
			get { return _role; }
			set { _role = value; }
		}

		public string RoleName
		{
			get { return _roleName; }
			set { _roleName = value; }
		}
		public int UserID
		{
			get { return _userID; }
			set { _userID = value; }
		}

		public string UserName
		{
			get { return _userName; }
			set { _userName = value; }
		}		

		//*********************************************************************
		//
		// GetAllUsers Static Method
		// Retrieves a list of all users.
		//
		//*********************************************************************

		public static UsersCollection GetAllUsers(int userID)
		{
			return GetUsers(userID, TTUser.UserRoleAdministrator);
		}

		//*********************************************************************
		//
		// GetUsers Static Method
		// Retrieves a list of users based on the specified userID and role.
		// The list returned is restricted by role.  For instance, users with
		// the role of Administrator can see all users, while users with the
		// role of Consultant can only see themselves.
		//
		//*********************************************************************
		
		public static UsersCollection GetUsers(int userID, string role)
		{
			string firstName = string.Empty;
			string lastName = string.Empty;

			DataSet ds = SqlHelper.ExecuteDataset(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString],
				"TT_ListUsers", userID, Convert.ToInt32(role)); 
			UsersCollection users = new UsersCollection();

			// Separate Data into a collection of Users.
			foreach(DataRow r in ds.Tables[0].Rows)
			{
				TTUser usr = new TTUser();
				usr.UserName = r["UserName"].ToString();
				usr.Role = r["RoleID"].ToString();
				usr.RoleName = r["RoleName"].ToString();
				usr.UserID = Convert.ToInt32(r["UserID"]);
				usr.Name = GetDisplayName(usr.UserName, ref firstName, ref lastName);
				usr.FirstName = firstName;
				usr.LastName = lastName;
				users.Add(usr);
			}
			return users;
		}

		//*********************************************************************
		//
		// GetDisplayName static method
		// Gets the user's first and last name from the specified TTUser account source, which is
		// set in Web.confg.
		//
		//*********************************************************************

		public static string GetDisplayName(string userName, ref string firstName, ref string lastName)
		{
			string displayName = string.Empty;
			string dbName = string.Empty;

			// The DirectoryHelper class will attempt to get the user's first 
			// and last name from the specified account source.
			DirectoryHelper.FindUser(userName, ref firstName, ref lastName);

			// If the first and last name could not be retrieved, return the TTUserName.
			if (firstName.Length > 0 || lastName.Length > 0)
			{
				displayName = firstName + " " + lastName;
			}
			else
			{
				dbName = GetDisplayNameFromDB(userName);
				if (dbName != string.Empty)
					displayName = dbName;
				else
					displayName = userName;
			}
			return displayName;
		}

		public static string GetDisplayNameFromDB(string userName)
		{
			string displayName = string.Empty;
			displayName = Convert.ToString(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString], 
									"TT_GetUserDisplayName", userName));
			return displayName;
		}

		//*********************************************************************
		//
		// ListManagers Static Method
		// Retrieves a list of users with the role of Project Manager.
		//
		//*********************************************************************
	
		public static UsersCollection ListManagers()
		{
			string firstName = string.Empty;
			string lastName = string.Empty;
			
			DataSet ds = SqlHelper.ExecuteDataset(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString], 
							CommandType.StoredProcedure, "TT_ListManagers"); 
			UsersCollection managersArray = new UsersCollection();

			// Separate Data into a list of collections.
			foreach(DataRow r in ds.Tables[0].Rows)
			{
				TTUser usr = new TTUser();
				usr.UserName = r["UserName"].ToString();
				usr.Role = r["RoleID"].ToString();
				usr.UserID = Convert.ToInt32(r["UserID"]);
				usr.Name = GetDisplayName(usr.UserName, ref firstName, ref lastName);
				usr.FirstName = firstName;
				usr.LastName = lastName;
				managersArray.Add(usr);
			}
			return managersArray;
		}

		//*********************************************************************
		//
		// Remove static method
		// Removes a user from database
		//
		//*********************************************************************
		
		public static void Remove (int userID)
		{
			SqlHelper.ExecuteNonQuery(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString], 
				"TT_DeleteUser", userID);
		}

		//*********************************************************************
		//
		// Load method
		// Retrieve user information from the data access layer
		// returns True if user information is loaded successfully, false otherwise.
		//
		//*********************************************************************
		public bool Load ()
		{
			// Get the user's information from the database
			DataSet ds = SqlHelper.ExecuteDataset(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString],
				"TT_GetUserByUserName", _userName); 

			if (ds.Tables[0].Rows.Count < 1)
				return false;

			DataRow dr = ds.Tables[0].Rows[0];
			_userID = Convert.ToInt32(dr["UserID"]);
			_userName = dr["UserName"].ToString();
			_role = dr["RoleID"].ToString();
			_password = dr["Password"] == DBNull.Value ? "":dr["Password"].ToString();
			_displayName = GetDisplayName(_userName, ref _firstName, ref _lastName);
			
			return true;
		}

		//*********************************************************************
		//
		// Save method
		// Add or update user information in the database depending on the TTUserID.
		// Returns True if saved successfully, false otherwise.
		//
		//*********************************************************************

		public bool Save ()
		{
			bool isUserFound = false;
			bool isUserActiveManager = true;
			return Save(false, ref isUserFound, ref isUserActiveManager);
		}

		//*********************************************************************
		//
		// Save method
		// Add or update user information in the database depending on the TTUserID.
		// Returns True if saved successfully, false otherwise.
		//
		//*********************************************************************

		public bool Save (bool checkUsername, ref bool isUserFound, ref bool isUserActiveManager)
		{
			// Determines whether object needs update or to be inserted.
			if (_userID == 0)
				return Insert(checkUsername, ref isUserFound);
			else if (_userID > 0)
				return Update(ref isUserActiveManager);
			else
			{
				_userID = 0;
				return false;
			}
		}

		private bool Insert(bool checkUsername, ref bool isUserFound)
		{
			string firstName = string.Empty;
			string lastName = string.Empty;
			isUserFound = false;

			if (ConfigurationSettings.AppSettings[Web.Global.CfgKeyUserAcctSource] != "None")
			{
				// Check to see if the user is in the NT SAM or Active Directory before inserting them
				// into the Time Tracker database.  If a first or last name is returned, the user exists and
				// can be inserted into the Time Tracker database.
				if (checkUsername)
				{
					TTUser.GetDisplayName(_userName, ref firstName, ref lastName);
					isUserFound  = (firstName != string.Empty || lastName != string.Empty);
				}
			}
			else
			{
				checkUsername = false;
				isUserFound = true;
			}

			if ((checkUsername && isUserFound) || (!checkUsername))
			{																	  
				_userID = Convert.ToInt32(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString], "TT_AddUser", 
					_userName, _password, _displayName, Convert.ToInt32(_role)));
				isUserFound = true;
			}
			return (_userID > 0);
		}
		
		//*********************************************************************
		//
		// UsersDB.Login() Method 
		//
		// The Login method validates a email/password pair against credentials
		// stored in the users database.  If the email/password pair is valid,
		// the method returns user's name.
		//						  
		// Other relevant sources:
		//     + UserLogin Stored Procedure
		//
		//*********************************************************************
		
		public string Login(string email, string password)
		{
			string userName = string.Empty;
			userName = Convert.ToString(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString], "TT_UserLogin", email, password));

			if (userName != "" || userName !=string.Empty)
				return userName;
			else
				return string.Empty;

		}

		private bool Update(ref bool isUserActiveManger)
		{
			// if new user role is a consultant, check if user is a active manager of one or more project. if so, no update is applied 
			if (_role == UserRoleConsultant && 
				(isUserActiveManger = (0 < Convert.ToInt32(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString], "TT_GetManagerProjectCount", _userID)))))
				return false;
            
			return (0 < Convert.ToInt32(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString], "TT_UpdateUser", 
				 _userID, _userName, _password, _displayName, Convert.ToInt32(_role))));
		}
	}	
}
