@using Moonlight.Shared.Components.ErrorBoundaries
@using Moonlight.Shared.Components.Auth
@using Moonlight.App.Database.Entities
@using Moonlight.App.Extensions
@using Moonlight.App.Models.Misc
@using Moonlight.App.Services
@using Moonlight.App.Services.Interop
@using Moonlight.App.Services.Sessions
@using Moonlight.App.Events

@layout ThemeInit
@implements IDisposable
@inherits LayoutComponentBase

@inject IJSRuntime JsRuntime
@inject IdentityService IdentityService
@inject SessionService SessionService
@inject NavigationManager NavigationManager
@inject EventSystem Event
@inject ToastService ToastService
@inject SmartTranslateService SmartTranslateService
@inject IpBanService IpBanService

<GlobalErrorBoundary>
    @{
        var uri = new Uri(NavigationManager.Uri);
        var pathParts = uri.LocalPath.Split("/").Reverse();

        var title = "";

        foreach (var pathPart in pathParts)
        {
            if (!string.IsNullOrEmpty(pathPart))
            {
                if (pathPart == pathParts.Last())
                    title += $"{pathPart.FirstCharToUpper()} ";
                else
                    title += $"{pathPart.FirstCharToUpper()} - ";
            }
        }
    }

    <CascadingValue Value="User">
        <PageTitle>@(string.IsNullOrEmpty(title) ? "Dashboard - " : title)Moonlight</PageTitle>

        <div class="d-flex flex-column flex-root app-root" id="kt_app_root">
            <div class="app-page flex-column flex-column-fluid" id="kt_app_page">
                <canvas id="snow" class="snow-canvas"></canvas>

                @{
                    //TODO: Add a way to disable the snow
                }

                <PageHeader></PageHeader>
                <div class="app-wrapper flex-column flex-row-fluid" id="kt_app_wrapper">
                    <Sidebar></Sidebar>
                    <div class="app-main flex-column flex-row-fluid" id="kt_app_main">
                        <div class="d-flex flex-column flex-column-fluid">
                            <div id="kt_app_content" class="app-content flex-column-fluid">
                                <div id="kt_app_content_container" class="app-container container-fluid">
                                    <div class="mt-10">
                                        <SoftErrorBoundary>
                                            @if (!IsIpBanned)
                                            {
                                                if (UserProcessed)
                                                {
                                                    if (uri.LocalPath != "/login" &&
                                                        uri.LocalPath != "/passwordreset" &&
                                                        uri.LocalPath != "/register")
                                                    {
                                                        if (User == null)
                                                        {
                                                            <Login></Login>
                                                        }
                                                        else
                                                        {
                                                            if (User.Status == UserStatus.Banned)
                                                            {
                                                                <BannedAlert></BannedAlert>
                                                            }
                                                            else if (User.Status == UserStatus.Disabled)
                                                            {
                                                                <DisabledAlert></DisabledAlert>
                                                            }
                                                            else if (User.Status == UserStatus.PasswordPending)
                                                            {
                                                                <PasswordChangeView></PasswordChangeView>
                                                            }
                                                            else if (User.Status == UserStatus.DataPending)
                                                            {
                                                                <UserDataSetView></UserDataSetView>
                                                            }
                                                            else
                                                            {
                                                                @Body

                                                                <RatingPopup/>
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        if (uri.LocalPath == "/login")
                                                        {
                                                            <Login></Login>
                                                        }
                                                        else if (uri.LocalPath == "/register")
                                                        {
                                                            <Register></Register>
                                                        }
                                                        else if (uri.LocalPath == "/passwordreset")
                                                        {
                                                            <PasswordReset></PasswordReset>
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    <div class="modal d-block">
                                                        <div class="modal-dialog modal-dialog-centered mw-900px">
                                                            <div class="modal-content">
                                                                <div class="pt-2 modal-body py-lg-10 px-lg-10">
                                                                    <h2>@(SmartTranslateService.Translate("Authenticating"))...</h2>
                                                                    <p class="mt-3 fw-normal fs-6">@(SmartTranslateService.Translate("Verifying token, loading user data"))</p>
                                                                </div>
                                                            </div>
                                                        </div>
                                                    </div>
                                                }
                                            }
                                            else
                                            {
                                                <div class="modal d-block">
                                                    <div class="modal-dialog modal-dialog-centered mw-900px">
                                                        <div class="modal-content">
                                                            <div class="pt-2 modal-body py-lg-10 px-lg-10">
                                                                <h2>@(SmartTranslateService.Translate("Your ip has been banned"))</h2>
                                                                <p class="mt-3 fw-normal fs-6">@(SmartTranslateService.Translate("Your ip address has been banned by an admin"))</p>
                                                            </div>
                                                        </div>
                                                    </div>
                                                </div>
                                            }
                                        </SoftErrorBoundary>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <Footer></Footer>
                    </div>
                </div>
            </div>
        </div>
    </CascadingValue>
</GlobalErrorBoundary>

@code
{
    private User? User;
    private bool UserProcessed = false;

    private bool IsIpBanned = false;

    protected override void OnInitialized()
    {
        AddBodyAttribute("data-kt-app-page-loading", "on");
    }

    protected override void OnAfterRender(bool firstRender)
    {
    //Initialize classes and attributes for layout with dark sidebar
        AddBodyAttribute("data-kt-app-reset-transition", "true");

        AddBodyAttribute("data-kt-app-layout", "dark-sidebar");
        AddBodyAttribute("data-kt-app-header-fixed", "true");
        AddBodyAttribute("data-kt-app-sidebar-fixed", "true");
        AddBodyAttribute("data-kt-app-sidebar-hoverable", "true");
        AddBodyAttribute("data-kt-app-sidebar-push-header", "true");
        AddBodyAttribute("data-kt-app-sidebar-push-toolbar", "true");
        AddBodyAttribute("data-kt-app-sidebar-push-footer", "true");
        AddBodyAttribute("data-kt-app-toolbar-enabled", "true");

        AddBodyClass("app-default");
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            try
            {
                IsIpBanned = await IpBanService.IsBanned();
                
                if(IsIpBanned)
                    await InvokeAsync(StateHasChanged);
                
                await Event.On<Object>("ipBan.update", this, async _ =>
                {
                    IsIpBanned = await IpBanService.IsBanned();
                    NavigationManager.NavigateTo(NavigationManager.Uri, true);
                });

                User = await IdentityService.Get();
                UserProcessed = true;
                await InvokeAsync(StateHasChanged);

                await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-reset-transition");
                await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-page-loading");
                await JsRuntime.InvokeVoidAsync("KTMenu.createInstances");
                await JsRuntime.InvokeVoidAsync("KTDrawer.createInstances");

                await SessionService.Register();

                NavigationManager.LocationChanged += (sender, args) => { SessionService.Refresh(); };

                if (User != null)
                {
                    await Event.On<SupportChatMessage>(
                        $"supportChat.{User.Id}.message",
                        this,
                        async message =>
                        {
                            if (!NavigationManager.Uri.EndsWith("/support") && message.Sender != User)
                            {
                                await ToastService.Info($"Support: {message.Content}");
                            }
                        });
                }

                RunDelayedMenu(0);
                RunDelayedMenu(1);
                RunDelayedMenu(3);
                RunDelayedMenu(5);
            }
            catch (Exception)
            {
    // ignored
            }
        }
    }

    public async void Dispose()
    {
        SessionService.Close();

        if (User != null)
        {
            await Event.Off($"supportChat.{User.Id}.message", this);
        }
    }

    private void AddBodyAttribute(string attribute, string value)
    {
        JsRuntime.InvokeVoidAsync("document.body.setAttribute", attribute, value);
    }

    private void AddBodyClass(string className)
    {
        JsRuntime.InvokeVoidAsync("document.body.classList.add", className);
    }

    private void RunDelayedMenu(int seconds)
    {
        Task.Run(async () =>
        {
            try
            {
                await Task.Delay(TimeSpan.FromSeconds(seconds));
                await JsRuntime.InvokeVoidAsync("KTMenu.initHandlers");
            }
            catch (Exception e)
            {
    //Logger.Warn("Delayed menu error");
    //Logger.Warn(e);
            }
        });
    }
}