<script lang="ts">
  import { page } from '$app/state';
  import { goto } from '$app/navigation';
  import { ChevronDown, Compass, House, LibraryBig } from 'lucide-svelte';
  import { user, logout } from '$lib/auth/store.svelte';
  import { player } from '$lib/player/store.svelte';
  import { appName } from '$lib/branding';
  import MinstrelMark from './MinstrelMark.svelte';
  import PlayerBar from './PlayerBar.svelte';
  import SearchInput from './SearchInput.svelte';

  let { children } = $props<{ children: import('svelte').Snippet }>();

  let menuOpen = $state(false);
  let menuRef: HTMLElement | undefined = $state();
  let menuButtonRef: HTMLElement | undefined = $state();

  // Close the dropdown when the click was outside both the button and the menu.
  // The previous implementation used onclick={(e) => e.stopPropagation()} on the
  // menu container, which kept the window-level close-on-outside-click handler
  // from firing — but it also blocked SvelteKit's document-level link-click
  // interceptor, so clicking Admin/Settings inside the dropdown fell through
  // to the browser's native navigation (a full-page reload). On a hard reload,
  // /admin/+layout.ts's load function ran before bootstrap() settled the user
  // store, so the admin guard saw user.value === null and redirected to /.
  function handleWindowClick(e: MouseEvent) {
    if (!menuOpen) return;
    const target = e.target as Node | null;
    if (!target) return;
    if (menuRef?.contains(target) || menuButtonRef?.contains(target)) return;
    menuOpen = false;
  }

  async function handleLogout() {
    menuOpen = false;
    await logout();
    goto('/login', { replaceState: true });
  }

  function isActive(prefix: string): boolean {
    if (prefix === '/') return page.url.pathname === '/';
    return page.url.pathname.startsWith(prefix);
  }

  // Primary nav. Sits centered in the top bar (replaces the prior left
  // sidebar). Mirrors the Android top-app-bar treatment: three first-class
  // destinations, plus Library acting as a parent for Artists / Albums /
  // Liked / History / Playlists (tabs at /library/+layout.svelte).
  // Search + user menu live on the right side of the header (unchanged).
  // Library targets the Artists tab directly so SPA navigation doesn't
  // bounce through the /library 308-redirect. isActive('/library')
  // still matches all sub-routes by prefix so the active state covers
  // every tab.
  const navItems = [
    { href: '/',                 label: 'Home',     icon: House,       matchPrefix: '/' },
    { href: '/library/artists',  label: 'Library',  icon: LibraryBig,  matchPrefix: '/library' },
    { href: '/discover',         label: 'Discover', icon: Compass,     matchPrefix: '/discover' }
  ];
</script>

<svelte:window onclick={handleWindowClick} onkeydown={(e) => e.key === 'Escape' && (menuOpen = false)} />

<div class="grid h-screen grid-rows-[auto_1fr_auto] bg-background text-text-primary">
  <!-- 3-col grid so the middle column (nav) is centered on the page
       regardless of how wide the side columns are. With the prior
       flex+justify-center layout the nav's "available space" shifted
       whenever search or the user menu grew, so the nav drifted off
       window-center. Grid pins each column to a fixed lane. -->
  <header class="grid grid-cols-3 items-center border-b border-border bg-surface px-3 md:px-4 py-2 gap-3 md:gap-6">
    <a
      href="/"
      class="flex items-center gap-2 font-semibold text-sm md:text-base whitespace-nowrap justify-self-start"
    >
      <MinstrelMark size={20} class="shrink-0" />
      {appName()}
    </a>

    <nav aria-label="Primary" class="flex items-center justify-center gap-1 md:gap-2 justify-self-center">
      {#each navItems as item}
        {@const active = isActive(item.matchPrefix)}
        <a
          href={item.href}
          class="group flex items-center gap-2 rounded px-2 md:px-3 py-2 min-h-[44px]
                 text-text-secondary hover:text-text-primary hover:bg-surface-hover
                 focus-visible:ring-2 focus-visible:ring-accent
                 {active ? 'text-text-primary bg-surface-hover' : ''}"
          aria-current={active ? 'page' : undefined}
        >
          <item.icon size={18} strokeWidth={1.75} aria-hidden="true" />
          <span class="hidden sm:inline">{item.label}</span>
        </a>
      {/each}
    </nav>

    <div class="flex items-center gap-3 md:gap-6 justify-self-end min-w-0">
    <div class="hidden md:block min-w-0 max-w-xs flex-shrink">
      <SearchInput />
    </div>

    <div class="relative flex-shrink-0">
      <button
        bind:this={menuButtonRef}
        type="button"
        class="flex items-center gap-1.5 rounded px-2 md:px-3 py-1 hover:bg-surface-hover focus-visible:ring-2 focus-visible:ring-accent min-h-[44px]"
        aria-haspopup="menu"
        aria-expanded={menuOpen}
        onclick={() => (menuOpen = !menuOpen)}
      >
        <span class="hidden sm:inline max-w-[8ch] truncate">{user.value?.username ?? ''}</span>
        <ChevronDown
          size={16}
          strokeWidth={1}
          class="transition-transform {menuOpen ? 'rotate-180' : ''}"
          aria-hidden="true"
        />
      </button>
      {#if menuOpen}
        <div
          bind:this={menuRef}
          class="absolute right-0 z-50 mt-1 w-40 rounded border border-border bg-surface shadow"
          role="menu"
          tabindex="-1"
        >
          <a
            href="/settings"
            role="menuitem"
            class="block px-3 py-2 text-sm hover:bg-surface-hover"
            onclick={() => (menuOpen = false)}
          >
            Settings
          </a>
          {#if user.value?.is_admin}
            <a
              href="/admin"
              role="menuitem"
              class="block px-3 py-2 text-sm hover:bg-surface-hover"
              onclick={() => (menuOpen = false)}
            >
              Admin
            </a>
          {/if}
          <button
            type="button"
            role="menuitem"
            class="block w-full border-t border-border px-3 py-2 text-left text-sm hover:bg-surface-hover"
            onclick={handleLogout}
          >
            Log out
          </button>
        </div>
      {/if}
    </div>
    </div>
  </header>

  <!-- Subtle 1200x600 radial highlight at the top of the scroll
       area fades the slate tone (fs-iron with alpha) into the
       background. Adds depth so the page doesn't read as a flat
       slab. color-mix lets the gradient theme-track in case the
       palette token ever shifts. -->
  <main
    class="overflow-y-auto p-4"
    style="background-image: radial-gradient(ellipse 1200px 600px at 50% -100px,
      color-mix(in srgb, var(--fs-iron) 60%, transparent), transparent 70%);"
  >
    {@render children?.()}
  </main>

  {#if player.current}
    <PlayerBar />
  {/if}
</div>
