@page "/admin/users"

@using Moonlight.Core.UI.Components.Navigations
@using MoonCore.Abstractions
@using Moonlight.Core.Database.Entities
@using BlazorTable
@using MoonCore.Exceptions
@using MoonCoreUI.Services
@using Moonlight.Core.Models.Abstractions
@using Moonlight.Core.Models.Forms.Users

@inject AlertService AlertService
@inject IAuthenticationProvider AuthenticationProvider

@attribute [RequirePermission(1000)]

<AdminUsersNavigation Index="0"/>

<AutoCrud TItem="User"
                  TCreateForm="CreateUserForm"
                  TUpdateForm="UpdateUserForm"
                  Title=""
                  Load="Load"
                  CustomAdd="Add"
                  ValidateUpdate="ValidateUpdate">
    <View>
        <CrudColumn TItem="User" Field="@(x => x.Id)" Title="Id" Filterable="true"/>
        <CrudColumn TItem="User" Field="@(x => x.Email)" Title="Email" Filterable="true"/>
        <CrudColumn TItem="User" Field="@(x => x.Username)" Title="Username" Filterable="true"/>
        <CrudColumn TItem="User" Field="@(x => x.CreatedAt)" Title="Created at" />
    </View>
    <Actions>
        <WButton OnClick="() => ChangePassword(context)" CssClasses="btn btn-icon btn-primary">
            <i class="bx bx-sm bxs-key"></i>
        </WButton>
    </Actions>
</AutoCrud>

@code
{
    private User[] Load(Repository<User> repository)
    {
        return repository.Get().ToArray();
    }

    private async Task ChangePassword(User user)
    {
        var newPassword = await AlertService.Text($"Enter a new password for {user.Username}", "");

        // This handles empty and canceled input
        if (string.IsNullOrEmpty(newPassword))
            return;

        await AuthenticationProvider.ChangePassword(user, newPassword);
    }

    private async Task Add(User user)
    {
        var result = await AuthenticationProvider.Register(user.Username, user.Email, user.Password);

        if (result == null)
            throw new DisplayException("An unknown error occured while creating user");
    }

    // To notify the authentication provider before we update the data in the database, we call it here
    private async Task ValidateUpdate(User user)
    {
        await AuthenticationProvider.ChangeDetails(user, user.Email, user.Username);
    }
}