@using Hcs.WebApp.Services
@using Microsoft.AspNetCore.Identity
@using Microsoft.EntityFrameworkCore

@inject RoleManager<AppRole> RoleManager
@inject UsersService UsersService
@inject DialogService DialogService

<RadzenTemplateForm TItem="InputModel" Data=@Input Submit="@DoAddUserAsync">
    <RadzenAlert Visible="@hasError" AlertStyle="AlertStyle.Danger" Variant="Variant.Flat" Shade="Shade.Lighter" AllowClose="false">
        @errorMessage
    </RadzenAlert>
    <RadzenStack Gap="1rem" class="rz-p-sm-4">
        <RadzenFormField Text="Логин" Variant="Variant.Outlined">
            <ChildContent>
                <RadzenTextBox Name="UserName" @bind-Value=@Input.UserName AutoCompleteType="AutoCompleteType.Username" />
            </ChildContent>
            <Helper>
                <RadzenRequiredValidator Component="UserName" Text="Поле 'Логин' обязательно к заполнению" />
                <RadzenLengthValidator Component="UserName" Min="5" Text="Длина поля 'Логин' должна быть не меньше 5" />
                <RadzenLengthValidator Component="UserName" Max="30" Text="Длина поля 'Логин' должна быть не больше 30" />
            </Helper>
        </RadzenFormField>
        <RadzenFormField Text="Роль" Variant="Variant.Outlined">
            <ChildContent>
                <RadzenDropDown Data="@roles" TextProperty="Name" @bind-Value="@Input.Role" Name="Role" style="width: 100%" />
            </ChildContent>
        </RadzenFormField>
        <RadzenFormField Text="Пароль" Variant="Variant.Outlined">
            <ChildContent>
                <RadzenPassword Name="Password" @bind-Value=@Input.Password AutoCompleteType="AutoCompleteType.NewPassword" />
            </ChildContent>
            <Helper>
                <RadzenRequiredValidator Component="Password" Text="Поле 'Пароль' обязательно к заполнению" />
                <RadzenLengthValidator Component="Password" Min="6" Text="Длина поля 'Пароль' должна быть не меньше 6" />
                <RadzenLengthValidator Component="Password" Max="100" Text="Длина поля 'Пароль' должна быть не больше 100" />
            </Helper>
        </RadzenFormField>
        <RadzenFormField Text="Повторите пароль" Variant="Variant.Outlined">
            <ChildContent>
                <RadzenPassword Name="ConfirmPassword" @bind-Value=@Input.ConfirmPassword AutoCompleteType="AutoCompleteType.NewPassword" />
            </ChildContent>
            <Helper>
                <RadzenRequiredValidator Component="ConfirmPassword" Text="Поле 'Повторите пароль' обязательно к заполнению" />
                <RadzenCompareValidator Value=@Input.Password Component="ConfirmPassword" Text="Пароли должны совпадать" />
            </Helper>
        </RadzenFormField>
        <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.End" Gap="0.5rem">
            <RadzenButton ButtonType="ButtonType.Submit" Disabled="@inProgress" Text="Создать"></RadzenButton>
            <RadzenButton Click="@DoClose" ButtonStyle="ButtonStyle.Light" Disabled="@inProgress" Text="Отмена"></RadzenButton>
        </RadzenStack>
    </RadzenStack>
</RadzenTemplateForm>

@code {
    sealed class InputModel
    {
        public string UserName { get; set; } = "";

        public AppRole Role { get; set; }

        public string Password { get; set; } = "";

        public string ConfirmPassword { get; set; } = "";
    }

    IEnumerable<AppRole> roles;
    bool inProgress;
    bool hasError;
    string errorMessage;

    [SupplyParameterFromForm]
    InputModel Input { get; set; } = new();

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        roles = await RoleManager.Roles.OrderBy(x => x.Priority).ToListAsync();

        Input.Role = roles.First();
    }

    async Task DoAddUserAsync(InputModel input)
    {
        if (inProgress) return;

        inProgress = true;
        hasError = false;

        try
        {
            var result = await UsersService.CreateUserAsync(input.UserName, input.Role.Name, input.Password);
            if (result.Succeeded)
            {
                DialogService.Close(true);
            }
            else
            {
                hasError = true;
                errorMessage = string.Join(", ", result.Errors.Select(x => x.Description));
            }
        }
        catch (Exception e)
        {
            hasError = true;
            errorMessage = e.Message;
        }
        finally
        {
            inProgress = false;
        }
    }

    void DoClose()
    {
        if (inProgress) return;

        DialogService.Close(false);
    }
}
