using System.Text.Json;
using System.Threading.Tasks;
using Dacryptero.Notifications;
using Dacryptero.Session.Fido;

namespace Dacryptero.Web.Events.Receive;

public class AccountRegister : ReceiveBase
{
    public string Database { get; private set; } = "";

    public string? Key { get; private set; }

    public string Username { get; private set; } = "";

    public string Password { get; private set; } = "";

    public override async Task Execute(ExecuteArgs args)
    {
        DB.DBSingleController? db = null;
        DB.Creation.NewDBInfo? newDB = null;
        DB.Creation.UnlockedDBInfo? unlocked = null;
        if (Key is not null)
        {
            if (!args.Connection.NewDBInfo.TryGetValue(Key, out newDB))
            {
                args.SendNotification(Notification.Error(
                    "Invalid database",
                    "database not found"
                ));
                return;
            }
        }
        else
        {
            if ((db = args.Connection.DB.GetController(Database)) is null)
            {
                args.SendNotification(Notification.Error(
                    "Invalid database",
                    "database not found"
                ));
                return;
            }
            if (!args.Connection.UnlockedDBs.TryGetValue(Database, out unlocked))
            {
                args.SendNotification(Notification.Error(
                    "Database locked",
                    "The database is locked. Try to unlock it first."
                ));
                return;
            }
        }

        if (Username == "")
        {
            args.SendNotification(Notification.Error(
                "Invalid username",
                "Username is empty"
            ));
            return;
        }

        if (Password.Length < 12 || Password.Length > 128)
        {
            args.SendNotification(Notification.Error(
                "Invalid password",
                "Invalid password length"
            ));
            return;
        }

        if (Config.Default.Security.Tfa)
        {
#if DEBUG
            var config = UserBase.GetConfiguration("localhost:8000");
#else
            var config = UserBase.GetConfiguration(args.Connection.Host);
#endif
            RegisterUserBase user;
            if (db is null)
                user = new RegisterUserNew(args.Connection, config, this, newDB!);
            else user = new RegisterUserEx(args.Connection, config, this, db, unlocked!.Key);
            args.Connection.FidoLogin = user;

            var (command, value) = user.GetMessage();
            await args.Connection.Send(new Send.AccountFidoRequest(command, Database, value))
                .ConfigureAwait(false);
        }
        else
        {
            throw new System.NotImplementedException();
        }
    }

    public override void ReadJsonContent(JsonElement json)
    {
        Database = json.GetProperty("database").GetString() ?? "";
        Key = json.TryGetProperty("key", out JsonElement node) ? node.GetString() : null;
        Username = json.GetProperty("username").GetString() ?? "";
        Password = json.GetProperty("password").GetString() ?? "";
    }
}