@using Moonlight.App.Services.Interop
@using Moonlight.App.Exceptions
@using Moonlight.App.Services
@using Moonlight.App.ApiClients.CloudPanel
@using Moonlight.App.ApiClients.Daemon
@using Moonlight.App.ApiClients.Modrinth
@using Moonlight.App.ApiClients.Wings
@using Moonlight.App.Helpers
@using Stripe
@inherits ErrorBoundaryBase

@inject AlertService AlertService
@inject ConfigService ConfigService
@inject SmartTranslateService SmartTranslateService
@inject NavigationManager NavigationManager

@if (HardCrashed)
{
    <div class="card card-flush h-md-100">
        <div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
            <div class="mb-10">
                <div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
                    <span class="me-2">
                        <TL>Ooops. This page is crashed</TL>
                    </span>
                </div>
                <div class="text-center">
                    <TL>This page is crashed. The error has been reported to the moonlight team. Meanwhile you can try reloading the page</TL>
                </div>
            </div>
        </div>
    </div>
}
else if (SoftCrashed)
{
    <div class="card card-body bg-danger mb-5">
        <span class="text-center">
            @(ErrorMessage)
        </span>
    </div>
    
    @ChildContent
}
else
{
    @ChildContent
}

@code
{
    private bool HardCrashed = false;
    private bool SoftCrashed = false;
    private string ErrorMessage = "";

    protected override void OnInitialized()
    {
        NavigationManager.LocationChanged += OnPathChanged;
    }

    private void OnPathChanged(object? sender, LocationChangedEventArgs e)
    {
        if (SoftCrashed)
            SoftCrashed = false;
        
        StateHasChanged();
    }

    protected override async Task OnErrorAsync(Exception exception)
    {
        if (ConfigService.DebugMode)
        {
            Logger.Verbose(exception);
        }
        
        if (exception is DisplayException displayException)
        {
            if (displayException.DoNotTranslate)
            {
                await SoftCrash(displayException.Message);
            }
            else
            {
                await SoftCrash(SmartTranslateService.Translate(displayException.Message));
            }
        }
        else if (exception is CloudflareException cloudflareException)
        {
            await SoftCrash(SmartTranslateService.Translate("Error from cloudflare: ") + cloudflareException.Message);
        }
        else if (exception is WingsException wingsException)
        {
            await SoftCrash(SmartTranslateService.Translate("Error from wings: ") + wingsException.Message);
            
            Logger.Warn($"Wings exception status code: {wingsException.StatusCode}");
        }
        else if (exception is DaemonException daemonException)
        {
            await SoftCrash(SmartTranslateService.Translate("Error from daemon: ") + daemonException.Message);

            Logger.Warn($"Wings exception status code: {daemonException.StatusCode}");
        }
        else if (exception is ModrinthException modrinthException)
        {
            await SoftCrash(SmartTranslateService.Translate("Error from modrinth: ") + modrinthException.Message);
        }
        else if (exception is CloudPanelException cloudPanelException)
        {
            await SoftCrash(SmartTranslateService.Translate("Error from cloudpanel: ") + cloudPanelException.Message);
        }
        else if (exception is NotImplementedException)
        {
            await SoftCrash(SmartTranslateService.Translate("This function is not implemented"));
        }
        else if (exception is StripeException stripeException)
        {
            await SoftCrash(SmartTranslateService.Translate("Error from stripe: ") + stripeException.Message);
        }
        else
        {
            Logger.Warn(exception);
            HardCrashed = true;
            await InvokeAsync(StateHasChanged);
        }
    }

    private Task SoftCrash(string message)
    {
        SoftCrashed = true;
        ErrorMessage = message;
        return Task.CompletedTask;
    }
}