@namespace OpenArchival.Blazor.AdminPages.Shared
@using Microsoft.AspNetCore.Components.Web
@using MudBlazor
@using System.Text.RegularExpressions
@using System.ComponentModel.DataAnnotations
@using OpenArchival.DataAccess

<MudDialog>
    <TitleContent>
        @if (IsUpdate)
        {
            <MudText Typo="Typo.h6">Update User</MudText>
        } else
        {
            <MudText Typo="Typo.h6">Create a User</MudText>
        }
    </TitleContent>

    <DialogContent>
        <MudPaper Class="pa-4">
            <MudForm @ref="_mudForm" @bind-IsValid="@_isFormValid" OnEnterPressed="@(() => _mudForm.Validate())">
                <MudTextField @bind-Value="Model.Username" T="string" Label="Email" Required="true" RequiredError="Email is required!"
                              Validation="@(new EmailAddressAttribute { ErrorMessage = @"The email address is invalid" })" />
                <MudTextField T="string"
                              @bind-Value="@Model.Password"
                              Label="Password"
                              HelperText="Choose a strong password"
                              InputType="InputType.Password"
                              Validation="@(new Func<string, IEnumerable<string>>(PasswordStrength))" Required="!IsUpdate"
                              RequiredError="Password is required!" />

                <MudTextField T="string"
                              Label="Password" HelperText="Repeat the password" InputType="InputType.Password"
                              Validation="@(new Func<string, string>(PasswordMatch))" />
                <div class="d-flex align-center justify-space-between">
                    <MudSelect T="string" Label="Permissions" MultiSelection="true" Required="true" @bind-SelectedValues="Model.Roles">
                        <MudSelectItem T="string" Value="@UserRoles.Admin">@UserRoles.Admin</MudSelectItem>
                        <MudSelectItem T="string" Value="@UserRoles.Writer">@UserRoles.Writer</MudSelectItem>
                    </MudSelect>
                </div>
            </MudForm>
        </MudPaper>
    </DialogContent>

    <DialogActions>
        <MudButton 
            Variant="Variant.Filled" 
            Color="Color.Primary" 
            Class="ml-auto"
        OnClick="@(OnCancel)">Cancel</MudButton>

        <MudButton 
            Variant="Variant.Filled" 
            Color="Color.Primary" 
            Disabled="@(!_isFormValid)" 
            Class="ml-auto"
        OnClick="@(OnRegister)">
            @if (IsUpdate)
            {
                <MudText Typo="Typo.button">Update</MudText> 
            } else
            {

                <MudText Typo="Typo.button">Register</MudText> 
            }
    </MudButton>
    </DialogActions>
</MudDialog>

@code {
    [Parameter]
    public UserDto Model { get; set; } = new();

    [CascadingParameter]
    IMudDialogInstance MudDialog { get; set; } = default!;

    [Parameter]
    public bool IsUpdate { get; set; } = false;

    private MudForm _mudForm { get; set; } = default!;

    private bool _isFormValid { get; set; } = false;

    private IEnumerable<string> PasswordStrength(string pw)
    {
        // Do not require the password be entered on an update, we could be changing just the roles or email
        if (IsUpdate && string.IsNullOrWhiteSpace(Model.Password))
        {
            yield return "";
            yield break;
        }

        if (string.IsNullOrWhiteSpace(pw) && !IsUpdate)
        {
            yield return "Password is required!";
            yield break;
        }
        if (pw.Length < 8)
            yield return "Password must be at least of length 8";
        if (!Regex.IsMatch(pw, @"[A-Z]"))
            yield return "Password must contain at least one capital letter";
        if (!Regex.IsMatch(pw, @"[a-z]"))
            yield return "Password must contain at least one lowercase letter";
        if (!Regex.IsMatch(pw, @"[0-9]"))
            yield return "Password must contain at least one digit";
    }

    private string? ValidatePermissions(bool value)
    {
        return null;
    }

    private string? PasswordMatch(string arg) { 
        return Model.Password != arg ? "Passwords don't match" : null;
    }
    
    private void OnCancel(MouseEventArgs args)
    {
        MudDialog.Cancel();
    }

    private void OnRegister(MouseEventArgs args)
    {
        MudDialog.Close(DialogResult.Ok(Model));
    }
}
