<!-- [DEF:Sidebar:Component] -->
<script>
  /**
   * @TIER: CRITICAL
   * @PURPOSE: Persistent left sidebar with resource categories navigation
   * @LAYER: UI
   * @RELATION: BINDS_TO -> sidebarStore
   * @SEMANTICS: Navigation
   * @INVARIANT: Always shows active category and item
   *
   * @UX_STATE: Idle -> Sidebar visible with current state
   * @UX_STATE: Toggling -> Animation plays for 200ms
   * @UX_FEEDBACK: Active item highlighted with different background
   * @UX_RECOVERY: Click outside on mobile closes overlay
   *
   * @TEST_CONTRACT Component_Sidebar ->
   * {
   *   required_props: {},
   *   optional_props: {},
   *   invariants: [
   *       "Highlights active category and sub-item based on current page URL",
   *       "Toggles sidebar via toggleSidebar store action",
   *       "Closes mobile overlay on click outside"
   *   ]
   * }
   * @TEST_FIXTURE idle_state -> {}
   * @TEST_EDGE mobile_open -> shows mobile overlay mask
   * @TEST_INVARIANT navigation -> verifies: [idle_state]
   */

  import { onMount } from "svelte";
  import { page } from "$app/stores";
  import {
    sidebarStore,
    toggleSidebar,
    setActiveItem,
    closeMobile,
  } from "$lib/stores/sidebar.js";
  import { t } from "$lib/i18n";
  import { browser } from "$app/environment";
  import Icon from "$lib/ui/Icon.svelte";

  function buildCategories() {
    return [
      {
        id: "dashboards",
        label: $t.nav?.dashboards,
        icon: "dashboard",
        tone: "from-sky-100 to-sky-200 text-sky-700 ring-sky-200",
        path: "/dashboards",
        subItems: [{ label: $t.nav?.overview, path: "/dashboards" }],
      },
      {
        id: "datasets",
        label: $t.nav?.datasets,
        icon: "database",
        tone: "from-emerald-100 to-emerald-200 text-emerald-700 ring-emerald-200",
        path: "/datasets",
        subItems: [{ label: $t.nav?.all_datasets, path: "/datasets" }],
      },
      {
        id: "storage",
        label: $t.nav?.storage,
        icon: "storage",
        tone: "from-amber-100 to-amber-200 text-amber-800 ring-amber-200",
        path: "/storage",
        subItems: [
          { label: $t.nav?.backups, path: "/storage/backups" },
          {
            label: $t.nav?.repositories,
            path: "/storage/repos",
          },
        ],
      },
      {
        id: "reports",
        label: $t.nav?.reports,
        icon: "reports",
        tone: "from-violet-100 to-fuchsia-100 text-violet-700 ring-violet-200",
        path: "/reports",
        subItems: [{ label: $t.nav?.reports, path: "/reports" }],
      },
      {
        id: "admin",
        label: $t.nav?.admin,
        icon: "admin",
        tone: "from-rose-100 to-rose-200 text-rose-700 ring-rose-200",
        path: "/admin",
        subItems: [
          { label: $t.nav?.admin_users, path: "/admin/users" },
          { label: $t.nav?.admin_roles, path: "/admin/roles" },
          { label: $t.nav?.settings, path: "/settings" },
        ],
      },
    ];
  }

  let categories = buildCategories();

  let isExpanded = true;
  let activeCategory = "dashboards";
  let activeItem = "/dashboards";
  let isMobileOpen = false;
  let expandedCategories = new Set(["dashboards"]);

  // Subscribe to sidebar store
  $: if ($sidebarStore) {
    isExpanded = $sidebarStore.isExpanded;
    activeCategory = $sidebarStore.activeCategory;
    activeItem = $sidebarStore.activeItem;
    isMobileOpen = $sidebarStore.isMobileOpen;
  }

  // Reactive categories to update translations
  $: categories = buildCategories();

  // Update active item when page changes
  $: if ($page && $page.url.pathname !== activeItem) {
    const matched = categories.find((cat) =>
      $page.url.pathname.startsWith(cat.path),
    );
    if (matched) {
      activeCategory = matched.id;
      activeItem = $page.url.pathname;
    }
  }

  function handleItemClick(category) {
    console.log(`[Sidebar][Action] Clicked category ${category.id}`);
    setActiveItem(category.id, category.path);
    closeMobile();
    if (browser) {
      window.location.href = category.path;
    }
  }

  function handleCategoryToggle(categoryId, event) {
    event.stopPropagation();

    if (!isExpanded) {
      console.log(
        `[Sidebar][Action] Expand sidebar and category ${categoryId}`,
      );
      toggleSidebar();
      expandedCategories.add(categoryId);
      expandedCategories = expandedCategories;
      return;
    }

    console.log(`[Sidebar][Action] Toggle category ${categoryId}`);
    if (expandedCategories.has(categoryId)) {
      expandedCategories.delete(categoryId);
    } else {
      expandedCategories.add(categoryId);
    }
    expandedCategories = expandedCategories;
  }

  function handleSubItemClick(categoryId, path) {
    console.log(`[Sidebar][Action] Clicked sub-item ${path}`);
    setActiveItem(categoryId, path);
    closeMobile();
    if (browser) {
      window.location.href = path;
    }
  }

  function handleToggleClick(event) {
    event.stopPropagation();
    console.log("[Sidebar][Action] Toggle sidebar");
    toggleSidebar();
  }

  function handleOverlayClick() {
    console.log("[Sidebar][Action] Close mobile overlay");
    closeMobile();
  }

  // Close mobile overlay on route change
  $: if (isMobileOpen && $page) {
    closeMobile();
  }
</script>

<!-- Mobile overlay (only on mobile) -->
{#if isMobileOpen}
  <div
    class="fixed inset-0 bg-black/50 z-20 md:hidden"
    on:click={handleOverlayClick}
    on:keydown={(e) => e.key === "Escape" && handleOverlayClick()}
    role="presentation"
  ></div>
{/if}

<!-- Sidebar -->
<div
  class="fixed left-0 top-0 z-30 flex h-screen flex-col border-r border-slate-200 bg-white shadow-sm transition-[width] duration-200 ease-in-out
    {isExpanded ? 'w-sidebar' : 'w-sidebar-collapsed'}
    {isMobileOpen
    ? 'translate-x-0 w-sidebar'
    : '-translate-x-full md:translate-x-0'}"
>
  <!-- Header -->
  <div
    class="flex items-center border-b border-slate-200 p-4 {isExpanded
      ? 'justify-between'
      : 'justify-center'}"
  >
    {#if isExpanded}
      <span class="font-semibold text-gray-800 flex items-center gap-2">
        <span
          class="inline-flex h-6 w-6 items-center justify-center rounded-md bg-gradient-to-br from-slate-100 to-slate-200 text-slate-700 ring-1 ring-slate-200"
        >
          <Icon name="layers" size={14} />
        </span>
        {$t.nav?.menu}
      </span>
    {:else}
      <span class="text-xs text-gray-500">M</span>
    {/if}
  </div>

  <!-- Navigation items -->
  <nav class="flex-1 overflow-y-auto py-2">
    {#each categories as category}
      <div>
        <!-- Category Header -->
        <div
          class="flex cursor-pointer items-center justify-between px-4 py-3 transition-colors hover:bg-slate-100
            {activeCategory === category.id
            ? 'bg-primary-light text-primary md:border-r-2 md:border-primary'
            : ''}"
          on:click={(e) => handleCategoryToggle(category.id, e)}
          on:keydown={(e) =>
            (e.key === "Enter" || e.key === " ") &&
            handleCategoryToggle(category.id, e)}
          role="button"
          tabindex="0"
          aria-label={category.label}
          aria-expanded={expandedCategories.has(category.id)}
        >
          <div class="flex items-center">
            <span
              class="inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gradient-to-br ring-1 transition-all {category.tone}"
            >
              <Icon name={category.icon} size={16} strokeWidth={2} />
            </span>
            {#if isExpanded}
              <span class="ml-3 text-sm font-medium truncate"
                >{category.label}</span
              >
            {/if}
          </div>
          {#if isExpanded}
            <Icon
              name="chevronDown"
              size={16}
              class="text-gray-400 transition-transform duration-200 {expandedCategories.has(
                category.id,
              )
                ? 'rotate-180'
                : ''}"
            />
          {/if}
        </div>

        <!-- Sub Items (only when expanded) -->
        {#if isExpanded && expandedCategories.has(category.id)}
          <div class="bg-gray-50 overflow-hidden transition-all duration-200">
            {#each category.subItems as subItem}
              <div
                class="flex items-center px-4 py-2 pl-12 cursor-pointer transition-colors text-sm text-gray-600 hover:bg-gray-100 hover:text-gray-900
                  {activeItem === subItem.path
                  ? 'bg-primary-light text-primary'
                  : ''}"
                on:click={() => handleSubItemClick(category.id, subItem.path)}
                on:keydown={(e) =>
                  (e.key === "Enter" || e.key === " ") &&
                  handleSubItemClick(category.id, subItem.path)}
                role="button"
                tabindex="0"
              >
                {subItem.label}
              </div>
            {/each}
          </div>
        {/if}
      </div>
    {/each}
  </nav>

  <!-- Footer with Collapse button -->
  {#if isExpanded}
    <div class="border-t border-gray-200 p-4">
      <button
        class="flex items-center justify-center w-full px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"
        on:click={handleToggleClick}
      >
        <span
          class="mr-2 inline-flex h-6 w-6 items-center justify-center rounded-md bg-slate-100 text-slate-600"
        >
          <Icon name="chevronLeft" size={14} />
        </span>
        {$t.nav?.collapse}
      </button>
    </div>
  {:else}
    <div class="border-t border-gray-200 p-4">
      <button
        class="flex items-center justify-center w-full px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"
        on:click={handleToggleClick}
        aria-label={$t.nav?.expand_sidebar}
      >
        <Icon name="chevronRight" size={16} />
        <span class="ml-2">{$t.nav?.expand}</span>
      </button>
    </div>
  {/if}
</div>

<!-- [/DEF:Sidebar:Component] -->
