<script context="module" lang="ts">
  import type { NavSection } from '$lib/types/layout';

  export function isSectionVisible(section: NavSection, role?: string | null): boolean {
    if (!section.roles?.length) return true;
    if (!role) return false;
    return section.roles.includes(role);
  }
</script>

<script lang="ts">
  import { onMount } from 'svelte';
  import { get } from 'svelte/store';
  import {
    Moon,
    PanelLeftClose,
    PanelLeftOpen,
    PanelRightOpen,
    Sun
  } from 'lucide-svelte';
  import { navigationSections } from '$lib/config/navigation';
  import {
    setSidebarState,
    sidebarState,
    theme,
    toggleSidebar,
    toggleTheme
  } from '$lib/stores/layout';
  import { user } from '$lib/stores/auth';
  import type { SidebarState } from '$lib/types/layout';
  import SidebarSection from './SidebarSection.svelte';

  $: isExpanded = $sidebarState === 'expanded';
  $: isCollapsed = $sidebarState === 'collapsed';
  $: isHidden = $sidebarState === 'hidden';
  $: isDrawerOpen = $sidebarState !== 'hidden';

  $: visibleSections = navigationSections.filter((section) => isSectionVisible(section, $user?.role));

  function toggleWithShortcut(event: KeyboardEvent) {
    if ((event.metaKey || event.ctrlKey) && event.key === '\\') {
      event.preventDefault();
      toggleSidebar();
    }
  }

  $: if (typeof document !== 'undefined') {
    document.documentElement.setAttribute('data-sidebar', $sidebarState);
  }

  function getSidebarStateForWidth(width: number): SidebarState {
    if (width < 768) return 'hidden';
    if (width < 1280) return 'collapsed';
    return 'expanded';
  }

  onMount(() => {
    if (typeof window === 'undefined') return;

    const currentState = get(sidebarState);
    const desiredState = getSidebarStateForWidth(window.innerWidth);

    if (window.innerWidth < 768 && currentState !== 'hidden') {
      setSidebarState('hidden');
    } else if (currentState === 'hidden' && window.innerWidth >= 768) {
      setSidebarState(desiredState);
    }

    window.addEventListener('keydown', toggleWithShortcut);
    return () => window.removeEventListener('keydown', toggleWithShortcut);
  });
</script>

<div
  class="mobile-backdrop fixed inset-0 z-20 bg-black/40"
  class:hidden={!isDrawerOpen}
  aria-hidden={!isDrawerOpen}
  on:click={() => setSidebarState('hidden')}
  data-testid="sidebar-backdrop"
></div>

<aside
  class="fixed left-0 top-0 z-30 flex h-full flex-col border-r border-base-300 bg-base-200 transition-all duration-200 ease-out"
  class:w-60={isExpanded}
  class:w-16={isCollapsed}
  class:w-0={isHidden}
  class:overflow-hidden={isHidden}
  class:-translate-x-full={isHidden}
  class:translate-x-0={!isHidden}
  data-testid="sidebar"
>
  <div class="flex h-14 items-center justify-between border-b border-base-300 px-3">
    {#if isExpanded}
      <a href="/dashboard" class="text-lg font-bold">Headroom</a>
    {/if}

    <button class="btn btn-ghost btn-sm btn-circle" on:click={toggleSidebar} aria-label="Toggle sidebar" data-testid="sidebar-toggle">
      {#if isExpanded}
        <PanelLeftClose size={18} />
      {:else if isCollapsed}
        <PanelLeftOpen size={18} />
      {:else}
        <PanelRightOpen size={18} />
      {/if}
    </button>
  </div>

  <nav class="flex-1 overflow-y-auto py-2">
    {#each visibleSections as section (section.title)}
      <SidebarSection {section} expanded={isExpanded} />
    {/each}
  </nav>

  <div class="border-t border-base-300 p-3">
    <button class="btn btn-ghost btn-sm w-full justify-start gap-2" class:justify-center={!isExpanded} on:click={toggleTheme} aria-label="Toggle theme" data-testid="theme-toggle">
      {#if $theme === 'light'}
        <Moon size={16} />
        {#if isExpanded}<span>Dark Mode</span>{/if}
      {:else}
        <Sun size={16} />
        {#if isExpanded}<span>Light Mode</span>{/if}
      {/if}
    </button>
  </div>
</aside>

<style>
  .mobile-backdrop {
    display: block;
  }

  @media (max-width: 767px) {
    aside {
      width: 15rem !important;
    }
  }

  @media (min-width: 768px) {
    .mobile-backdrop {
      display: none;
    }
  }
</style>
