// Copyright © 2017-2018 Atomic Software, LLC. All Rights Reserved.
// See LICENSE.md for full license information.

using Atom.Core;
using Atom.Core.Diagnostics;
using Atom.Core.Game;
using Atom.Core.Networking;
using Atom.Core.Networking.Messages.Structures.User;
using Atom.LoginServer.Services;

namespace Atom.LoginServer.Logic
{
    internal static class AccountLogic
    {
        internal static void Login(Client client, string Username, string Password, string spawnapps)
        {
            try
            {
                if (!Program.ServerInstance.IsODBCConnected)
                {
                    new PROTO_NC_USER_LOGINFAIL_ACK(LoginFailedErrorCode.DbError).Send(client);
                    return;
                }

                AccountService.Login(Username, Password, out int UserNo, out int IsBlocked, out int CanLogin);

                if (UserNo == -1)
                {
                    Log.Warning($"{Username} used the wrong credentials");
                    new PROTO_NC_USER_LOGINFAIL_ACK(LoginFailedErrorCode.WrongCredentials).Send(client);
                }
                else
                {
                    if (IsBlocked == 1)
                    {
                        Log.Warning($"{Username} is banned attempting to login");
                        new PROTO_NC_USER_LOGINFAIL_ACK(LoginFailedErrorCode.Banned).Send(client);
                    }
                    else
                    {
                        if (CanLogin == 0)
                        {
                            Log.Warning($"{Username} is trying to login while the server is down for maintenance");
                            new PROTO_NC_USER_LOGINFAIL_ACK(LoginFailedErrorCode.Maintenance).Send(client);
                        }
                        else
                        {
                            Log.Info($"{Username} logged in");

                            client.Account = new Account
                            {
                                Username = Username,
                                UserNo = UserNo
                            };

                            new PROTO_NC_USER_LOGIN_ACK(WMService.Worlds).Send(client);
                        }
                    }
                }
            }
            catch
            {
                new PROTO_NC_USER_LOGINFAIL_ACK(LoginFailedErrorCode.Exception).Send(client);
            }
        }

        internal static void LoginWithOTP(Client client, string otp)
        {
            if (!AccountService.CachedAccounts.TryGetValue(otp, out Account OldAccount))
            {
                new PROTO_NC_USER_LOGINFAIL_ACK(LoginFailedErrorCode.Timeout).Send(client);
                return;
            }

            AccountService.CachedAccounts.Remove(otp);

            client.Account = OldAccount;
            new PROTO_NC_USER_LOGIN_ACK(WMService.Worlds).Send(client);

            Log.Info($"{client.Account.Username} logged back in");
        }
    }
}
