@using MoonCore.Helpers
@using MoonCore.Exceptions
@using System.Diagnostics
@using Moonlight.Core.Services

@inject IdentityService IdentityService

@inherits ErrorBoundaryBase

@if (Crashed || CurrentException != null)
{
    if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" || (IdentityService.IsLoggedIn && IdentityService.CurrentUser.Permissions >= 9000))
    {
        if (Exception != null)
        {
            <IconAlert Icon="bx-error" Color="danger" Title="An unhandled exception has been thrown">
                <div class="card border border-danger">
                    <div class="card-body fs-5">
                        @(Formatter.FormatLineBreaks(Exception.ToStringDemystified()))
                    </div>
                </div>
            </IconAlert>
        }
        else
        {
            <IconAlert Icon="bx bx-error" Color="danger" Title="An unknown error has occured">
                An unknown error has occured while processing your request. Please refresh the page in order to continue. If this error persists please contact the administrator
            </IconAlert>
        }
    }
    else
    {
        <IconAlert Icon="bx bx-error" Color="danger" Title="An unknown error has occured">
            An unknown error has occured while processing your request. Please refresh the page in order to continue. If this error persists please contact the administrator
        </IconAlert>
    }
}
else
{
    if (ErrorMessages.Any())
    {
        foreach (var errorMessage in ErrorMessages)
        {
            <div class="alert alert-danger bg-danger text-white p-3 mb-5 fw-semibold fs-5 text-center">
                @errorMessage
            </div>
        }
    }
    
    @ChildContent
}

@code 
{
    private bool Crashed = false;
    private List<string> ErrorMessages = new();
    private Exception? Exception;

    protected override async Task OnErrorAsync(Exception exception)
    {
        if (exception is DisplayException displayException)
        {
            ErrorMessages.Add(displayException.Message);

            Task.Run(async () =>
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
                ErrorMessages.Remove(displayException.Message);
                await InvokeAsync(StateHasChanged);
            });
        }
        else
        {
            Exception = exception;
            Crashed = true;

            var username = IdentityService.IsLoggedIn ? IdentityService.CurrentUser.Username : "Guest";
            Logger.Warn($"A crash occured in the view of '{username}'");
            Logger.Warn(exception);
        }
        
        Recover();

        // Note:
        // This fixes a weird behavior when a error in a component render call happens, e.g. missing parameter
        // Without this, it would not show the error, just nothing
        Task.Run(async () =>
        {
            await InvokeAsync(StateHasChanged);
        });
    }
}