@page "/account/security"

@using System.ComponentModel.DataAnnotations
@using Moonlight.Core.Services
@using Moonlight.Core.UI.Components.Navigations
@using Moonlight.Core.Models.Forms
@using Moonlight.Core.Models.Abstractions
@using MoonCore.Exceptions
@using Moonlight.Core.UI.Components.Auth

@inject IdentityService IdentityService
@inject ToastService ToastService
@inject IAuthenticationProvider AuthenticationProvider

<div class="card card-body bg-primary mb-8">
    <div class="d-flex align-items-center">
        <span class="fs-2 fw-semibold">
            @* the @@@ looks weird, ik that, it will result in @username *@

            @@@IdentityService.GetUser().Username
        </span>
    </div>
</div>

<AccountNavigation Index="1"/>

<div class="row g-5">
    <div class="col-md-6 col-12">
        <div class="card">
            <div class="card-body">
                <FastForm @ref="PasswordForm" Model="PasswordModel" OnConfigure="OnConfigurePasswordForm" />
            </div>
            <div class="card-footer d-flex justify-content-end">
                <WButton OnClick="ChangePassword" CssClasses="btn btn-primary">Save changes</WButton>
            </div>
        </div>
    </div>
    <div class="col-md-6 col-12">
        <div class="card h-100">
            <div class="card-body">
                <TwoFactorWizard />
            </div>
        </div>
    </div>
    <div class="col-md-6 col-12">
        <div class="card h-100">
            <div class="card-body">
                <h3>Cookies</h3>
                <p class="my-2 text-muted fs-5">
                    This specifies if you would like to personalize your experience with optional cookies.
                </p>
                <div class="form-check form-switch">
                    @if (CookieConsent)
                    {
                    <input @onclick="() => SetCookieConsent(false)" class="form-check-input" type="checkbox" role="switch" checked="checked">
                    }
                    else
                    {
                    <input @onclick="() => SetCookieConsent(true)" class="form-check-input" type="checkbox" role="switch">
                    }
                </div>
            </div>
        </div>
    </div>
</div>

@code
{
    private ChangePasswordForm PasswordModel = new();
    private FastForm<ChangePasswordForm> PasswordForm;

    private bool CookieConsent;

    protected override async Task OnInitializedAsync()
    {
        CookieConsent = await IdentityService.HasFlag("CookieConsent");
    }

    private async Task SetCookieConsent(bool flag)
    {
        await IdentityService.SetFlag("CookieConsent", flag);
        
        await ToastService.Success("Successfully changed cookie preferences");
        await InvokeAsync(StateHasChanged);
    }

    private void OnConfigurePasswordForm(FastFormConfiguration<ChangePasswordForm> configuration)
    {
        configuration.AddProperty(x => x.Password)
            .WithComponent<StringComponent>(component =>
            {
                component.ColumnsMd = 6;
                component.Type = "password";
            })
            .WithValidation(FastFormValidators.Required)
            .WithValidation(x => x.Length >= 8 ? ValidationResult.Success : new("The password must be at least 8 characters long"))
            .WithValidation(x => x.Length <= 256 ? ValidationResult.Success : new("The password must not be longer than 256 characters"));

        configuration.AddProperty(x => x.RepeatedPassword)
            .WithComponent<StringComponent>(component =>
            {
                component.ColumnsMd = 6;
                component.Type = "password";
            });
    }

    private async Task ChangePassword()
    {
        if(!await PasswordForm.Submit())
            return;
        
        if (PasswordModel.Password != PasswordModel.RepeatedPassword)
            throw new DisplayException("The passwords do not match");
        
        await AuthenticationProvider.ChangePassword(IdentityService.GetUser(), PasswordModel.Password);
        
        await ToastService.Success("Successfully changed password");
        await IdentityService.Authenticate();
    }
}