using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
using Aitex.Common.Util;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.Key;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.Account;
using MECF.Framework.Common.Account.Extends;
using MECF.Framework.Common.Account.Permissions;

namespace Aitex.Core.Account
{
	public sealed class AccountService : IAccountService
	{
		#region Properties

		public string Module => "System";

		#endregion

		#region Common Operations

		public void RegisterViews(List<string> views)
		{
			AccountManager.Instance.RegisterViews(views);
		}

		public bool SaveAllRolesPermission(Dictionary<string, Dictionary<string, ViewPermission>> data)
		{
			if (Singleton<KeyManager>.Instance.IsExpired)
			{
				EV.PostMessage("System", EventEnum.DefaultWarning, "Software is expired. Can not do the operation");
				return false;
			}

			return AccountManager.Instance.SaveAllRolesPermission(data);
		}

		public SerializableDictionary<string, string> GetAllViewList()
		{
			return AccountManager.GetAllViewList();
		}

		public string GetProcessViewPermission()
		{
			string filename = Path.Combine(PathManager.GetCfgDir(), "RolePermission.xml");
			XmlDocument xmlDocument = new XmlDocument();
			try
			{
				xmlDocument.Load(filename);
				return xmlDocument.InnerXml;
			}
			catch (Exception ex)
			{
				LOG.Write(ex);
				return "<Aitex></Aitex>";
			}
			finally
			{
			}
		}

		public bool SaveProcessViewPermission(string viewXML)
		{
			try
			{
				string filename = Path.Combine(PathManager.GetCfgDir(), "RolePermission.xml");
				XmlDocument xmlDocument = new XmlDocument();
				xmlDocument.LoadXml(viewXML);
				XmlTextWriter xmlTextWriter = new XmlTextWriter(filename, null);
				xmlTextWriter.Formatting = Formatting.Indented;
				xmlDocument.Save(xmlTextWriter);
				xmlTextWriter.Close();
				return true;
			}
			catch (Exception ex)
			{
				LOG.Write(ex);
				return false;
			}
		}

		public List<AppMenu> GetAllMenus()
		{
			return AccountExManager.Instance.RoleAccountLoader.GetAllMenus();
		}

		#endregion

		#region Roles Operations

		public IEnumerable<Role> GetRolesIncludeSuper()
		{
			return AccountExManager.Instance.RoleAccountLoader.GetRoles(true);
		}


		public List<Role> GetRoles()
		{
			return AccountExManager.Instance.RoleAccountLoader.GetRoles();
		}

		public bool UpdateRole(Role role)
		{
			return AccountExManager.Instance.RoleAccountLoader.UpdateRole(role);
		}

		public bool DeleteRole(string roleId)
		{
			return AccountExManager.Instance.RoleAccountLoader.DeleteRole(roleId);
		}

		/// <inheritdoc />
		public string GetAvailableRoleID()
		{
			return AccountExManager.Instance.RoleAccountLoader.GetAvailableRoleID();
		}

		/// <inheritdoc />
		public Role GetRoleByID(string id)
		{
			return AccountExManager.Instance.RoleAccountLoader.GetRoles().FirstOrDefault(x => x.RoleId == id);
		}

		public Role GetRoleByName(string name)
		{
			return AccountExManager.Instance.RoleAccountLoader.GetRoles().FirstOrDefault(x => x.RoleName == name);
		}

		/// <inheritdoc />
		public bool CheckRoleNotDuplicated(string id, string name)
		{
			var sameNameRole = GetRoleByName(name);
			return sameNameRole == null || sameNameRole.RoleId == id;
		}

		#endregion

		#region Accounts Operations

		public GetAccountInfoResult GetAccountInfo(string accountId)
		{
			return AccountManager.Instance.GetAccountInfo(accountId);
		}

		public List<AccountEx> GetAccountsIncludeSuper()
		{
			return AccountExManager.Instance.RoleAccountLoader.GetAccounts(true);
		}

		public List<AccountEx> GetAccounts()
		{
			return AccountExManager.Instance.RoleAccountLoader.GetAccounts();
		}

		public CreateAccountResult CreateAccount(Account newAccount)
		{
			if (Singleton<KeyManager>.Instance.IsExpired)
			{
				EV.PostMessage("System", EventEnum.DefaultWarning, "Software is expired. Can not do the operation");
				return new CreateAccountResult();
			}

			EV.PostInfoLog(Module, $"Create account{newAccount}.");
			LOG.Write($"Account operation, Create user {newAccount.AccountId}.");
			return AccountManager.Instance.CreateAccount(newAccount);
		}

		public DeleteAccountResult DeleteAccount(string accountId)
		{
			if (Singleton<KeyManager>.Instance.IsExpired)
			{
				EV.PostMessage("System", EventEnum.DefaultWarning, "Software is expired. Can not do the operation");
				return new DeleteAccountResult();
			}

			EV.PostInfoLog(Module, $"Delete account {accountId}.");
			return AccountManager.Instance.DeleteAccount(accountId);
		}

		public UpdateAccountResult UpdateAccount(Account account)
		{
			if (Singleton<KeyManager>.Instance.IsExpired)
			{
				EV.PostMessage("System", EventEnum.DefaultWarning, "Software is expired. Can not do the operation");
				return new UpdateAccountResult();
			}

			EV.PostInfoLog(Module, $"Update {account} account information.");
			return AccountManager.Instance.UpdateAccount(account);
		}

		public bool UpdateAccountEx(AccountEx account)
		{
			return AccountExManager.Instance.RoleAccountLoader.UpdateAccount(account);
		}

		public bool DeleteAccountEx(string loginName)
		{
			return AccountExManager.Instance.RoleAccountLoader.DeleteAccount(loginName);
		}

		public ChangePwdResult ChangePassword(string accountId, string newPassword)
		{
			if (Singleton<KeyManager>.Instance.IsExpired)
			{
				EV.PostMessage("System", EventEnum.DefaultWarning, "Software is expired. Can not do the operation");
				return new ChangePwdResult();
			}

			EV.PostInfoLog(Module, $"Change user {accountId} password.");
			LOG.Write($"Account operation, change user {accountId} password.");
			return AccountManager.Instance.ChangePassword(accountId, newPassword);
		}

		public bool CheckPassword(string accountId, string passwordMD5)
		{
			return AccountExManager.Instance.CheckPassword(accountId, passwordMD5);
		}

		#endregion

		#region Login Sessions Operations

		public List<Account> GetLoginUsers()
		{
			return AccountManager.Instance.GetLoginUserList();
		}

		public async Task<LoginResult> LoginEx(string userName, string password, string role,
			LoginClientInfo clientInfo)
		{
			return await AccountExManager.Instance.Login(userName, password, role, clientInfo);
		}

		public void CancelLoginRequest(string userName)
		{
			AccountExManager.Instance.CancelLoginRequest(userName);
		}

		public void ConfirmLoginRequest(string userName)
		{
			AccountExManager.Instance.ConfirmedLoginRequest(userName);
		}

		public void RejectLoginRequest(string userName)
		{
			AccountExManager.Instance.RejectLoginRequest(userName);
		}


		public void LogoutEx(Guid myToken)
		{
			AccountExManager.Instance.Logout(myToken);
		}

		public void KickUserOut(string accountId, string kickoutReason)
		{
			EV.PostInfoLog(Module, $"Force user {accountId} logout system，reason：{kickoutReason}.");
			try
			{
			}
			catch
			{
			}

			AccountManager.Instance.Kickout(accountId, kickoutReason);
		}

		/// <summary>
		/// 报告客户端处于活动状态。
		/// </summary>
		/// <param name="myToken">客户端登录凭据令牌。</param>
		/// <returns></returns>
		public CredentialKeepAliveCheckResult KeepAlive(Guid myToken)
		{
			return CredentialManager.Instance.KeepAlive(myToken);
		}

		#endregion

		#region Permission Operations

		public List<AppMenu> GetAccessibleMenusByRole(string roleId)
		{
			return AccountExManager.Instance.RoleAccountLoader.GetAccessibleMenusByRole(roleId);
		}

		public MenuPermissionEnum GetMenuPermission(string roleId, string menuName)
		{
			return AccountExManager.Instance.RoleAccountLoader.GetMenuPermission(roleId, menuName);
		}
		
		#endregion

	}
}
