@page "/Account/Manage/GenerateRecoveryCodes"

@using Microsoft.AspNetCore.Identity
@using Wave.Data

@inject UserManager<ApplicationUser> UserManager
@inject IdentityUserAccessor UserAccessor
@inject IdentityRedirectManager RedirectManager
@inject ILogger<GenerateRecoveryCodes> Logger

<PageTitle>Generate two-factor authentication (2FA) recovery codes</PageTitle>

<BoardComponent>
    @if (recoveryCodes is not null) {
        <ShowRecoveryCodes RecoveryCodes="recoveryCodes.ToArray()" StatusMessage="@message" />
    } else {
        <BoardCardComponent Heading="Generate two-factor authentication (2FA) recovery codes">
            <Alert Type="Alert.MessageType.Warning" CanRemove="false">
                <p>
                    If you lose your device and don't have the recovery codes you will lose access to your account.
                </p>
                <p>
                    Generating new recovery codes does not change the keys used in authenticator apps. If you wish to change the key
                    used in an authenticator app you should <a href="Account/Manage/ResetAuthenticator">reset your authenticator keys.</a>
                </p>
            </Alert>
            <form @formname="generate-recovery-codes" @onsubmit="OnSubmitAsync" method="post" class="w-full">
                <AntiforgeryToken/>
                <button class="btn btn-error w-full mt-3" type="submit">Generate Recovery Codes</button>
            </form>
        </BoardCardComponent>
    }
</BoardComponent>

@code {
    private string? message;
    private ApplicationUser user = default!;
    private IEnumerable<string>? recoveryCodes;

    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        user = await UserAccessor.GetRequiredUserAsync(HttpContext);

        var isTwoFactorEnabled = await UserManager.GetTwoFactorEnabledAsync(user);
        if (!isTwoFactorEnabled)
        {
            throw new InvalidOperationException("Cannot generate recovery codes for user because they do not have 2FA enabled.");
        }
    }

    private async Task OnSubmitAsync()
    {
        var userId = await UserManager.GetUserIdAsync(user);
        recoveryCodes = await UserManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
        message = "You have generated new recovery codes.";

        Logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", userId);
    }
}
