@page "/Account/Login"

@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Identity
@using Wave.Data

@inject SignInManager<ApplicationUser> SignInManager
@inject ILogger<Login> Logger
@inject NavigationManager NavigationManager
@inject IdentityRedirectManager RedirectManager
@inject IStringLocalizer<Login> Localizer
@inject NavigationManager Navigation

<HeadContent>
	<meta name="robots" content="nofollow">
	<link rel="canonical" href="@(new UriBuilder(Navigation.BaseUri) { Scheme = "https", Port = -1, Path = "/account/login" }.Uri.AbsoluteUri)" />
</HeadContent>

<PageTitle>@Localizer["Title"]</PageTitle>

<StatusMessage Message="@_errorMessage" />

<BoardComponent CenterContent="true">
	<BoardCardComponent Heading="@Localizer["Title"]">
		<EditForm Model="Input" method="post" OnValidSubmit="LoginUser" FormName="login" class="w-full">
			<DataAnnotationsValidator />

			<InputLabelComponent LabelText="@Localizer["Email_Label"]" For="() => Input.Email">
				<InputText @bind-Value="Input.Email" class="input input-bordered w-full" autocomplete="username"
				           required aria-required="true" placeholder="@Localizer["Email_Placeholder"]" />
			</InputLabelComponent>
			<InputLabelComponent LabelText="@Localizer["Password_Label"]" For="() => Input.Password">
				<InputText @bind-Value="Input.Password" class="input input-bordered w-full" autocomplete="current-password" type="password"
				           required aria-required="true" placeholder="@Localizer["Password_Placeholder"]" />
			</InputLabelComponent>
			<div class="form-control">
				<label class="label cursor-pointer">
					<span class="label-text">@Localizer["RememberMe_Label"]</span>
					<InputCheckbox @bind-Value="Input.RememberMe" class="checkbox" />
				</label>
			</div>

			<button type="submit" class="btn btn-primary w-full">
				@Localizer["Submit"]
			</button>
		</EditForm>
		<ul class="mt-3 flex flex-col gap-1 text-center">
			<li>
				<a class="hover:link" href="Account/ForgotPassword">
					@Localizer["ResetPassword_Label"]
				</a>
			</li>
			<li>
				<a class="hover:link" href="@(NavigationManager.GetUriWithQueryParameters("Account/Register", new Dictionary<string, object?> { ["ReturnUrl"] = ReturnUrl }))">
					@Localizer["Register_Label"]
				</a>
			</li>
			<li>
				<a class="hover:link" href="Account/ResendEmailConfirmation">
					@Localizer["ResendMailConfirmation_Label"]
				</a>
			</li>
		</ul>
	</BoardCardComponent>
    
	<ExternalLoginPicker />
</BoardComponent>

@code {
    private string? _errorMessage;

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

    [SupplyParameterFromForm] 
    private InputModel Input { get; set; } = new();
    [SupplyParameterFromQuery] 
    private string? ReturnUrl { get; set; }

    protected override async Task OnInitializedAsync() {
        if (HttpMethods.IsGet(HttpContext.Request.Method)) {
            // Clear the existing external cookie to ensure a clean login process
            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
        }
    }

    public async Task LoginUser() {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, set lockoutOnFailure: true
        var result = await SignInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);

        if (result.Succeeded) {
            Logger.LogInformation("User logged in.");
            RedirectManager.RedirectTo(ReturnUrl);
        } else if (result.RequiresTwoFactor) {
            RedirectManager.RedirectTo("Account/LoginWith2fa",
                new() { ["returnUrl"] = ReturnUrl, ["rememberMe"] = Input.RememberMe });
        } else if (result.IsLockedOut) {
            Logger.LogWarning("User account locked out.");
            RedirectManager.RedirectTo("Account/Lockout");
        } else {
            _errorMessage = "Error: Invalid login attempt.";
        }
    }

    private sealed class InputModel {
        [Required] [EmailAddress] public string Email { get; set; } = "";

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; } = "";

        [Display(Name = "Remember me?")] public bool RememberMe { get; set; }
    }

}
