<script setup lang="ts">
/**
 * SidebarNav — registry-driven sidebar (AD-2.5-B1 / Plan 2.5 P4).
 *
 * Reads `APP_NAVIGATION` directly from `@/config/navigation`. This is the
 * single source of truth for sidebar items and breadcrumb derivation
 * (the breadcrumb side is served by `useBreadcrumb` over the same
 * registry). Prior to P4, this component received a `groups` prop the
 * parent layout built from `@/navigation/vertical`; the prop chain
 * (OrganizerLayoutV2 → AppSidebar → SidebarNav) is removed.
 *
 * Render contract:
 *   - Top-level leaf nodes (routeName set, no children) render as a row.
 *   - Top-level branch nodes (children set) render their label as a
 *     section heading followed by their children as rows.
 *   - Nodes without a `routeName` render as a non-clickable row
 *     (label-only) — dormant placeholders until their v2 page lands.
 */

import { useRoute } from 'vue-router'
import type { RouteLocationRaw } from 'unplugin-vue-router'
import Icon from '@/components/Icon.vue'
import { APP_NAVIGATION, type NavItem } from '@/config/navigation'

defineProps<{
  collapsed: boolean
}>()

const route = useRoute()

function isActive(item: NavItem): boolean {
  if (!item.routeName)
    return false

  const current = route.name

  if (typeof current !== 'string')
    return false

  return current === item.routeName
    || current.startsWith(`${item.routeName}-`)
}

// NavItem.routeName values come from APP_NAVIGATION and are always valid
// named routes from the RouteNamedMap when present — the cast to the typed
// RouterLink RouteLocationRaw is sound. Items without routeName render via
// the non-clickable branch (see template) so this function is never called
// for them.
function itemTo(item: NavItem): RouteLocationRaw {
  return { name: item.routeName } as RouteLocationRaw
}
</script>

<template>
  <nav class="flex-1 min-h-0 overflow-y-auto py-3.5 px-2.5 [scrollbar-width:thin]">
    <template
      v-for="topItem in APP_NAVIGATION"
      :key="topItem.key"
    >
      <!-- Branch node: section label + children -->
      <div
        v-if="topItem.children"
        class="[&:not(:first-child)]:mt-[18px]"
      >
        <div
          v-if="!collapsed"
          class="text-[11px] font-semibold text-surface-500 dark:text-surface-400 uppercase tracking-[0.06em] px-2.5 pb-1.5 whitespace-nowrap overflow-hidden"
        >
          {{ topItem.label }}
        </div>

        <template
          v-for="child in topItem.children"
          :key="child.key"
        >
          <!-- Leaf with route -->
          <RouterLink
            v-if="child.routeName"
            v-slot="{ href, navigate }"
            :to="itemTo(child)"
            custom
          >
            <a
              :href="href"
              class="flex items-center gap-3 py-[9px] rounded-md text-[13.5px] font-medium transition-[background,color] duration-150 whitespace-nowrap relative cursor-pointer w-full text-start min-w-0"
              :class="[
                collapsed ? 'justify-center px-0' : 'px-2.5',
                isActive(child)
                  ? 'nav-item-active bg-primary-50 dark:bg-primary-950 text-primary-600 dark:text-primary-400 font-semibold'
                  : 'text-surface-600 dark:text-surface-300 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-0',
              ]"
              :aria-current="isActive(child) ? 'page' : undefined"
              :aria-label="child.label"
              :title="collapsed ? child.label : undefined"
              @click="navigate"
            >
              <Icon
                v-if="child.icon"
                :name="child.icon"
                :size="18"
                class="flex-shrink-0"
              />

              <span
                v-if="!collapsed"
                class="overflow-hidden text-ellipsis min-w-0"
              >
                {{ child.label }}
              </span>
            </a>
          </RouterLink>

          <!-- Leaf without route: dormant placeholder -->
          <div
            v-else
            class="flex items-center gap-3 py-[9px] rounded-md text-[13.5px] font-medium whitespace-nowrap relative w-full text-start min-w-0 text-surface-400 dark:text-surface-500 cursor-not-allowed"
            :class="collapsed ? 'justify-center px-0' : 'px-2.5'"
            :aria-disabled="true"
            :title="collapsed ? child.label : undefined"
          >
            <Icon
              v-if="child.icon"
              :name="child.icon"
              :size="18"
              class="flex-shrink-0"
            />

            <span
              v-if="!collapsed"
              class="overflow-hidden text-ellipsis min-w-0"
            >
              {{ child.label }}
            </span>
          </div>
        </template>
      </div>

      <!-- Top-level leaf with route -->
      <RouterLink
        v-else-if="topItem.routeName"
        v-slot="{ href, navigate }"
        :to="itemTo(topItem)"
        custom
      >
        <a
          :href="href"
          class="flex items-center gap-3 py-[9px] rounded-md text-[13.5px] font-medium transition-[background,color] duration-150 whitespace-nowrap relative cursor-pointer w-full text-start min-w-0"
          :class="[
            collapsed ? 'justify-center px-0' : 'px-2.5',
            isActive(topItem)
              ? 'nav-item-active bg-primary-50 dark:bg-primary-950 text-primary-600 dark:text-primary-400 font-semibold'
              : 'text-surface-600 dark:text-surface-300 hover:bg-surface-100 dark:hover:bg-surface-800 hover:text-surface-900 dark:hover:text-surface-0',
          ]"
          :aria-current="isActive(topItem) ? 'page' : undefined"
          :aria-label="topItem.label"
          :title="collapsed ? topItem.label : undefined"
          @click="navigate"
        >
          <Icon
            v-if="topItem.icon"
            :name="topItem.icon"
            :size="18"
            class="flex-shrink-0"
          />

          <span
            v-if="!collapsed"
            class="overflow-hidden text-ellipsis min-w-0"
          >
            {{ topItem.label }}
          </span>
        </a>
      </RouterLink>

      <!-- Top-level leaf without route: dormant placeholder -->
      <div
        v-else
        class="flex items-center gap-3 py-[9px] rounded-md text-[13.5px] font-medium whitespace-nowrap relative w-full text-start min-w-0 text-surface-400 dark:text-surface-500 cursor-not-allowed"
        :class="collapsed ? 'justify-center px-0' : 'px-2.5'"
        :aria-disabled="true"
        :title="collapsed ? topItem.label : undefined"
      >
        <Icon
          v-if="topItem.icon"
          :name="topItem.icon"
          :size="18"
          class="flex-shrink-0"
        />

        <span
          v-if="!collapsed"
          class="overflow-hidden text-ellipsis min-w-0"
        >
          {{ topItem.label }}
        </span>
      </div>
    </template>
  </nav>
</template>

<style scoped>
/*
 * The active left-accent bar (.nav-item.active::before in crewli-starter main.css).
 * The bar sits at left:-10px — outside the row boundary. The parent <nav> is an
 * overflow-y-auto scroll container which clips cross-axis overflow, so a Tailwind
 * before: utility would be clipped by that parent overflow context. A <style scoped>
 * pseudo-element keeps the exception self-contained (customization order: Tailwind →
 * pt API → Aura → <style scoped> last resort with comment).
 */
.nav-item-active::before {
  content: "";
  position: absolute;
  left: -10px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  background: var(--p-primary-500, theme('colors.primary.500', #6366f1));
  border-radius: 0 3px 3px 0;
}
</style>
