@page "/Account/Manage/TwoFactorAuthentication"

@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Identity
@using OpenArchival.Blazor.Data

@inject UserManager<ApplicationUser> UserManager
@inject SignInManager<ApplicationUser> SignInManager
@inject IdentityUserAccessor UserAccessor
@inject IdentityRedirectManager RedirectManager

<PageTitle>Two-factor authentication (2FA)</PageTitle>

<MudText Typo="Typo.h6" GutterBottom="true">Two-factor authentication (2FA)</MudText>

<StatusMessage />

@if (canTrack)
{
    if (is2faEnabled)
    {
        if (recoveryCodesLeft == 0)
        {
            <MudAlert Variant="Variant.Text" Severity="Severity.Error">You have no recovery codes left.</MudAlert>

            <MudText Typo="Typo.body1" Class="pt-4">
                You must <MudLink Href="Account/Manage/GenerateRecoveryCodes">generate a new set of recovery codes</MudLink>
                before you can log in with a recovery code.
            </MudText>
        }
        else if (recoveryCodesLeft == 1)
        {
            <MudAlert Variant="Variant.Text" Severity="Severity.Warning">You have 1 recovery code left.</MudAlert>

            <MudText Typo="Typo.body1" Class="pt-4">
                You can <MudLink Href="Account/Manage/GenerateRecoveryCodes">generate a new set of recovery codes</MudLink>.
            </MudText>
        }
        else if (recoveryCodesLeft <= 3)
        {
            <MudAlert Variant="Variant.Text" Severity="Severity.Warning">You have @recoveryCodesLeft recovery codes left.</MudAlert>

            <MudText Typo="Typo.body1" Class="pt-4">
                You should <MudLink Href="Account/Manage/GenerateRecoveryCodes">generate a new set of recovery codes</MudLink>.
            </MudText>
        }

        if (isMachineRemembered)
        {
            <form style="display: inline-block" @formname="forget-browser" @onsubmit="OnSubmitForgetBrowserAsync" method="post">
                <AntiforgeryToken />
                
                <MudStaticButton Variant="Variant.Filled" Color="Color.Primary" FullWidth="true" FormAction="FormAction.Submit">Forget this browser</MudStaticButton>
            </form>
        }

        <MudLink Href="Account/Manage/Disable2fa">Disable 2FA</MudLink><br />
        <MudLink Href="Account/Manage/GenerateRecoveryCodes">Reset recovery codes</MudLink>
    }

    <MudText Typo="Typo.h6" GutterBottom="true">Authenticator app</MudText>

    @if (!hasAuthenticator)
    {
        <MudLink Href="Account/Manage/EnableAuthenticator">Add authenticator app</MudLink><br />
    }
    else
    {
        <MudLink Href="Account/Manage/EnableAuthenticator">Set up authenticator app</MudLink><br />
        <MudLink Href="Account/Manage/ResetAuthenticator">Reset authenticator app</MudLink>
    }
}
else
{
    <MudAlert Variant="Variant.Text" Severity="Severity.Error">Privacy and cookie policy have not been accepted.</MudAlert>

    <MudText Typo="Typo.body1" Class="pt-4">
        You must accept the policy before you can enable two factor authentication.
    </MudText>
}

@code {
    private bool canTrack;
    private bool hasAuthenticator;
    private int recoveryCodesLeft;
    private bool is2faEnabled;
    private bool isMachineRemembered;

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

    protected override async Task OnInitializedAsync()
    {
        var user = await UserAccessor.GetRequiredUserAsync(HttpContext);
        canTrack = HttpContext.Features.Get<ITrackingConsentFeature>()?.CanTrack ?? true;
        hasAuthenticator = await UserManager.GetAuthenticatorKeyAsync(user) is not null;
        is2faEnabled = await UserManager.GetTwoFactorEnabledAsync(user);
        isMachineRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(user);
        recoveryCodesLeft = await UserManager.CountRecoveryCodesAsync(user);
    }

    private async Task OnSubmitForgetBrowserAsync()
    {
        await SignInManager.ForgetTwoFactorClientAsync();

        RedirectManager.RedirectToCurrentPageWithStatus(
            "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code.",
            HttpContext);
    }
}
