@using System.Reflection;
@using MongoDB.Driver
@using Vaitr.Bus

@inherits ComponentBase
@implements IDisposable

@inject NavigationManager NavigationManager
@inject IMongoDatabase Database
@inject Bus Bus

<CascadingValue Value="RouteValues">
    <MudDrawer @bind-Open="@_open" ClipMode="DrawerClipMode.Docked" Variant="DrawerVariant.Responsive" Breakpoint="Breakpoint.Md" Elevation="2">
        <AuthorizeView>
            <Authorized>
                <div class="mt-5">
                    <MudNavMenu>
                        <CascadingValue Value="RouteValues">
                            @if (_content == Content.Account)
                            {
                                <Account />
                            }
                            else if (_content == Content.Customer)
                            {
                                <Customer />
                            }
                            else if (_content == Content.Host)
                            {
                                <Host />
                            }
                            else if (_content == Content.Scheduler)
                            {
                                <Scheduler />
                            }
                            else
                            {
                                <Main />
                            }
                        </CascadingValue>
                    </MudNavMenu>
                </div>
                <MudText Typo="Typo.subtitle1" Class="d-flex flex-wrap flex-grow-1 align-content-end justify-center mb-2" Style="opacity: 0.2;">
                    @(Assembly.GetEntryAssembly()?.GetName().Version)
                </MudText>
            </Authorized>
        </AuthorizeView>
    </MudDrawer>
</CascadingValue>

@code {
    [CascadingParameter] public IReadOnlyDictionary<string, object>? RouteValues { get; set; }

    private string _uri = string.Empty;
    private enum Content { Main, Account, Customer, Host, Scheduler }
    private Content _content = Content.Main;
    private IDisposable? _token;
    private bool _open = true;
    private bool _disposed;

    protected override void OnInitialized()
    {
        _token = Bus?.SubscribeAsync<string>(OnRefreshAsync, p => p == Events.Layout.Rendered);
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender) await OnRefreshAsync();
    }

    public void Toggle() => _open = !_open;

    public async ValueTask OnRefreshAsync(string? message = null, CancellationToken cancellationToken = default)
    {
        _uri = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
        if (_uri is null) return;

        if (_uri.StartsWith($"{Navigation.Account.Index}/")) _content = Content.Account;
        else if (_uri.StartsWith($"{Navigation.Management.Customers.Index}/")) _content = Content.Customer;
        else if (_uri.StartsWith($"{Navigation.Management.Hosts.Index}/")) _content = Content.Host;
        else if (_uri.StartsWith($"{Navigation.Management.Scheduler.Index}/")) _content = Content.Scheduler;
        else _content = Content.Main;

        await InvokeAsync(StateHasChanged);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        if (_disposed is false) return;
        if (disposing is false) return;

        try
        {
            _token?.Dispose();
        }
        finally
        {
            _disposed = true;
        }
    }
}