@implements IDisposable
@inject NavigationManager NavigationManager

<div class="app-shell">
    <a class="skip-link" href="#app-main">Skip to main content</a>

    <header class="app-shell-header">
        <div class="app-shell-bar">
            <div class="app-shell-brand-block">
                @if (BrandContent is null)
                {
                    <a class="app-shell-brand" href="/">
                        <span class="app-shell-brand-mark">RM</span>
                        <span class="app-shell-brand-copy">
                            <strong>Rolemaster DB</strong>
                            <span>Reference and lookup workspace</span>
                        </span>
                    </a>
                }
                else
                {
                    @BrandContent
                }
            </div>

            <nav class="app-shell-header-nav" aria-label="Primary">
                @if (PrimaryNavContent is null)
                {
                    <ShellPrimaryNav />
                }
                else
                {
                    @PrimaryNavContent
                }
            </nav>

            <div class="app-shell-header-omnibox">
                @if (OmniboxContent is not null)
                {
                    @OmniboxContent
                }
            </div>

            <div class="app-shell-header-actions">
                <button
                    type="button"
                    class="app-shell-menu-toggle"
                    aria-expanded="@isNavMenuOpen"
                    aria-controls="app-shell-drawer"
                    @onclick="ToggleNavMenu">
                    <span class="app-shell-menu-toggle-bar"></span>
                    <span class="app-shell-menu-toggle-bar"></span>
                    <span class="app-shell-menu-toggle-bar"></span>
                    <span class="visually-hidden">Toggle navigation</span>
                </button>
                @UtilityContent
            </div>
        </div>

        @if (ShortcutContent is not null)
        {
            <nav class="app-shell-shortcuts" aria-label="Pinned and recent shortcuts">
                @ShortcutContent
            </nav>
        }
    </header>

    <ShellOmniboxPalette />

    <main id="app-main" class="app-shell-main">
        <div class="content-shell">
            @ChildContent
        </div>
    </main>

    @if (isNavMenuOpen)
    {
        <button
            type="button"
            class="app-shell-drawer-backdrop"
            aria-label="Close navigation"
            @onclick="CloseNavMenu"></button>

        <aside id="app-shell-drawer" class="app-shell-drawer" aria-label="Primary navigation">
            <div class="app-shell-drawer-header">
                <strong>Navigate</strong>
                <button type="button" class="app-shell-drawer-close" @onclick="CloseNavMenu">
                    Close
                </button>
            </div>

            <ShellPrimaryNav />
        </aside>
    }

    <nav class="app-shell-mobile-nav" aria-label="Primary">
        <ShellPrimaryNav IsBottomNav="true" />
    </nav>
</div>

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    [Parameter]
    public RenderFragment? BrandContent { get; set; }

    [Parameter]
    public RenderFragment? PrimaryNavContent { get; set; }

    [Parameter]
    public RenderFragment? OmniboxContent { get; set; }

    [Parameter]
    public RenderFragment? ShortcutContent { get; set; }

    [Parameter]
    public RenderFragment? UtilityContent { get; set; }

    private bool isNavMenuOpen;

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

    private void ToggleNavMenu()
    {
        isNavMenuOpen = !isNavMenuOpen;
    }

    private void CloseNavMenu()
    {
        isNavMenuOpen = false;
    }

    private void HandleLocationChanged(object? sender, LocationChangedEventArgs args)
    {
        isNavMenuOpen = false;
        _ = InvokeAsync(StateHasChanged);
    }

    public void Dispose()
    {
        NavigationManager.LocationChanged -= HandleLocationChanged;
    }
}
