﻿using JLGames.RocketDriver.Actions.Localx;
using JLGames.RocketDriver.Actions.Utils;
using JLGames.RocketDriver.CSharp.Event;

namespace JLGames.RocketDriver.Games.LocalAccount
{
    public sealed class LocalAccountManager : EventDispatcher
    {
        private const string DatabaseKey = "dbk";
        private readonly LocalAccountDatabase<LocalAccount> m_Database = new LocalAccountDatabase<LocalAccount>();

        /// <summary>
        /// Current logging in Id
        /// 当前账号Id
        /// </summary>
        public string LoggingId => m_Database.LoggingId;

        /// <summary>
        /// Current logging in Account
        /// 当前账号信息
        /// </summary>
        public LocalAccount LoggingAccount => m_Database.LoggingAccount;

        /// <summary>
        /// Is there an account online
        /// 是否有账号在线中
        /// </summary>
        public bool ExistLogging => m_Database.ExistLogging;

        /// <summary>
        /// Find the account in the record by Id
        /// 通过Id查找记录中的帐号
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public LocalAccount FindAccountById(string userId)
        {
            return m_Database.FindAccountById(userId);
        }

        /// <summary>
        /// Find the account in the record by UserName
        /// 通过UserName查找记录中的帐号
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public LocalAccount FindAccountByName(string userName)
        {
            return m_Database.FindAccountByName(userName);
        }

        private LocalAccountManager()
        {
            InitDatabase();
        }

        private void InitDatabase()
        {
            var json = LocalStore.GetString(DatabaseKey);
            if (string.IsNullOrEmpty(json)) return;
            m_Database.FroamJosnOverride(json);
        }

        /// <summary>
        /// Guest Sign In onekey
        /// 游客一键登录
        /// </summary>
        public void SignGuestOnekey()
        {
            SignUpGuest();
            SignInGuest();
        }

        /// <summary>
        /// Sign up account and sign in onekey
        /// 一键注册账号并登录
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userPasswd"></param>
        /// <param name="userNick"></param>
        /// <returns></returns>
        public void SignOnekey(string userName, string userPasswd = null, string userNick = null)
        {
            var account = m_Database.FindAccountByName(userName);
            if (null == account)
            {
                var rsSignUp = SignUp(userName, userPasswd, userNick);
                if (!rsSignUp)
                {
                    return;
                }

                account = m_Database.FindAccountByName(userName);
            }

            if (account.UserId == m_Database.LoggingId)
            {
                NotifySignUp(account);
            }
            else
            {
                SignIn(userName, userPasswd);
            }
        }

        /// <summary>
        /// Guest sign up
        /// 游客注册
        /// </summary>
        public void SignUpGuest()
        {
            var guest = m_Database.Guest;
            if (null != guest) return;
            var guestId = IdentifyUtil.GetGuestId();
            var userName = "";
            var account = new LocalAccount(guestId, userName, IdentifyUtil.GetNickNameByTime(), "");
            m_Database.Add(account);
            SaveToLocal();
            NotifySignUp(account);
        }

        /// <summary>
        /// Sign up
        /// 注册账号
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userPasswd"></param>
        /// <param name="userNick"></param>
        /// <returns></returns>
        public bool SignUp(string userName, string userPasswd, string userNick = null)
        {
            if (string.IsNullOrEmpty(userName)) return false;
            if (m_Database.CheckExistByName(userName)) return false;

            var userId = IdentifyUtil.GetUserIdByTime();
            userNick = string.IsNullOrEmpty(userNick) ? IdentifyUtil.GetNickNameByTime() : userNick;
            var account = new LocalAccount(userId, userName, userPasswd, userNick);
            if (!m_Database.Add(account)) return false;

            SaveToLocal();
            NotifySignUp(account);
            return true;
        }

        /// <summary>
        /// Guest Sign in
        /// 游客登录
        /// </summary>
        /// <returns></returns>
        public bool SignInGuest()
        {
            var guest = m_Database.Guest;
            if (null == guest) return false;
            SignOutWithoutSave();
            m_Database.SignIn(guest.UserId);
            SaveToLocal();
            NotifySignIn(guest);
            return true;
        }

        /// <summary>
        /// Guest Sign in
        /// 登录账号
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="userPasswd"></param>
        /// <returns></returns>
        public bool SignIn(string userName, string userPasswd)
        {
            if (string.IsNullOrEmpty(userName)) return false;
            var account = m_Database.FindAccountByName(userName);
            if (account.UserId == m_Database.LoggingId) return false;
            if (!account.CheckPasswd(userPasswd)) return false;
            SignOutWithoutSave();
            var succ = m_Database.SignIn(account.UserId);
            if (!succ) return false;
            SaveToLocal();
            NotifySignIn(account);
            return true;
        }

        /// <summary>
        /// Sign out current account
        /// 登出账号
        /// </summary>
        /// <returns></returns>
        public bool SignOut()
        {
            var succ = SignOutWithoutSave();
            if (succ)
                SaveToLocal();
            return succ;
        }

        /// <summary>
        /// Set the newbie transition for the current account to Done
        /// 设置当前账号的新手过渡为完成
        /// </summary>
        public void FinishCurrentNewbie()
        {
            var account = m_Database.LoggingAccount;
            if (null == account) return;
            if (account.FinishNewbie())
            {
                SaveToLocal();
            }
        }

        private bool SignOutWithoutSave()
        {
            var userId = m_Database.SignOut();
            if (string.IsNullOrEmpty(userId)) return false;
            var account = m_Database.FindAccountById(userId);
            NotifySignOut(account);
            return true;
        }

        private void NotifySignUp(LocalAccount account)
        {
            DebugUtil.Log("注册通知：", account.UserName);
            DispatchEvent(LocalAccountEvents.EventSignUp, account);
        }

        private void NotifySignIn(LocalAccount account)
        {
            DebugUtil.Log("登录通知：", account.UserName);
            DispatchEvent(LocalAccountEvents.EventSignIn, account);
        }

        private void NotifySignOut(LocalAccount account)
        {
            DebugUtil.Log("登出通知：", account.UserName);
            DispatchEvent(LocalAccountEvents.EventSignOut, account);
        }

        private void SaveToLocal()
        {
            var data = m_Database.ToJson();
            LocalStore.SetString(DatabaseKey, data);
            LocalStore.SaveLocal();
        }

        //Static

        public static LocalAccountManager Shared { get; } = new LocalAccountManager();
    }
}