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

namespace Dacryptero.Web.Events.Receive;

public class FidoReceive : ReceiveBase
{
    public string Method { get; private set; } = "";

    public JsonElement Value { get; private set; }

    public override async Task Execute(ExecuteArgs args)
    {
        if (args.Connection.FidoLogin is null)
        {
            args.SendNotification(Notification.Error(
                "login failed",
                "there is no active login process"
            ));
            await args.Connection.Send(new Send.FidoResult("there is no active login process"))
                .ConfigureAwait(false);
            return;
        }
        if (Method != "login" && Method != "register")
        {
            args.SendNotification(Notification.Error(
                "login failed",
                "invalid method"
            ));
            await args.Connection.Send(new Send.FidoResult($"invalid method: {Method}"))
                .ConfigureAwait(false);
            return;
        }
        string? error;
        try { error = await args.Connection.FidoLogin.ValidateResult(Value)
            .ConfigureAwait(false); }
        catch (Exception e)
        {
            Serilog.Log.Fatal(e, "error during validation");
            error = "fatal error during validation";
        }
        if (error is not null)
        {
            args.SendNotification(Notification.Error(
                $"{Method} failed",
                error
            ));
            await args.Connection.Send(new Send.FidoResult($"validation error: {error}"))
                .ConfigureAwait(false);
            return;
        }

        await args.Connection.Send(new Send.FidoResult())
            .ConfigureAwait(false);
    }

    public override void ReadJsonContent(JsonElement json)
    {
        Method = json.GetProperty("method").GetString() ?? "";
        Value = json.GetProperty("value");
    }
}