@using Microsoft.AspNetCore.Components.Forms
@using Moonlight.App.Exceptions

<div class="form @CssClass">
    <EditForm @ref="EditForm" Model="Model" OnValidSubmit="ValidSubmit" OnInvalidSubmit="InvalidSubmit">
        <DataAnnotationsValidator></DataAnnotationsValidator>
        @if (Working)
        {
            <div class="d-flex flex-center flex-column">
                <span class="fs-1 spinner-border spinner-border-lg align-middle me-2"></span>
                <span class="mt-3 fs-5">Proccessing</span>
            </div>
        }
        else
        {
            if (ErrorMessages.Any())
            {
                <div class="alert alert-danger bg-danger text-white p-10 mb-3">
                    @foreach (var msg in ErrorMessages)
                    {
                        <TL>@(msg)</TL>
                        <br/>
                    }
                </div>
            }
            @(ChildContent)
        }
    </EditForm>
</div>

@code
{
    [Parameter]
    public object Model { get; set; }

    [Parameter]
    public Func<Task>? OnValidSubmit { get; set; }

    [Parameter]
    public Func<Task>? OnInvalidSubmit { get; set; }

    [Parameter]
    public Func<Task>? OnSubmit { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public string CssClass { get; set; }

    private EditForm EditForm;

    private List<string> ErrorMessages = new();

    private bool Working = false;

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            //EditForm.EditContext!.SetFieldCssClassProvider(new FieldCssHelper());
        }
    }

    private async Task ValidSubmit(EditContext context)
    {
        ErrorMessages.Clear();
        Working = true;

        await InvokeAsync(StateHasChanged);

        await Task.Run(async () =>
        {
            await InvokeAsync(async () =>
            {
                try
                {
                    if (OnValidSubmit != null)
                        await OnValidSubmit.Invoke();

                    if (OnSubmit != null)
                        await OnSubmit.Invoke();
                }
                catch (Exception e)
                {
                    if (e is DisplayException displayException)
                    {
                        ErrorMessages.Add(displayException.Message);
                    }
                    else
                        throw;
                }
            });

            Working = false;
            await InvokeAsync(StateHasChanged);
        });
    }

    private async Task InvalidSubmit(EditContext context)
    {
        ErrorMessages.Clear();
        context.Validate();

        foreach (var message in context.GetValidationMessages())
        {
            ErrorMessages.Add(message);
        }

        await InvokeAsync(StateHasChanged);

        try
        {
            if (OnInvalidSubmit != null)
                await OnInvalidSubmit.Invoke();

            if (OnSubmit != null)
                await OnSubmit.Invoke();
        }
        catch (Exception e)
        {
            if (e is DisplayException displayException)
            {
                ErrorMessages.Add(displayException.Message);
            }
            else
                throw e;
        }

        await InvokeAsync(StateHasChanged);
    }
}