﻿<template>
  <n-menu
    :collapsed="authStore.layoutCollapsed"
    :collapsed-width="72"
    :collapsed-icon-size="18"
    :options="menuOptions"
    :value="activePath"
    :indent="18"
    @update:value="handleSelect"
  />
</template>

<script setup lang="ts">
import { computed, h, type Component } from 'vue'
import { NIcon, type MenuOption } from 'naive-ui'
import * as LucideIcons from 'lucide-vue-next'
import { useRoute, useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import type { MenuNode } from '@/types/auth'

const route = useRoute()
const router = useRouter()
const authStore = useAuthStore()

function renderIcon(icon?: string | null) {
  if (!icon) return undefined
  const IconComp = LucideIcons[icon as keyof typeof LucideIcons] as unknown as Component | undefined
  if (!IconComp) return undefined
  return () => h(NIcon, null, { default: () => h(IconComp) })
}

function toOption(menu: MenuNode): MenuOption | null {
  if (!menu.visible) return null
  if (menu.type === 'BUTTON') return null

  const children = (menu.children ?? [])
    .map((item) => toOption(item))
    .filter((item): item is MenuOption => Boolean(item))

  const key = menu.path || `catalog-${menu.id}`
  return {
    key,
    label: menu.title,
    icon: renderIcon(menu.icon),
    children: children.length > 0 ? children : undefined
  }
}

const menuOptions = computed(() =>
  authStore.menus.map((item) => toOption(item)).filter((item): item is MenuOption => Boolean(item))
)

const activePath = computed(() => route.path)

function handleSelect(key: string) {
  if (key.startsWith('catalog-')) return
  router.push(key)
}
</script>

<style scoped>
:deep(.n-menu) {
  overflow-x: hidden;
  font-size: 13px;
}

:deep(.n-menu-item) {
  margin: 2px 0;
}

:deep(.n-menu-item-content) {
  color: #64748b;
  transition:
    background 0.18s ease,
    color 0.18s ease;
}

:deep(.n-menu-item-content-header),
:deep(.n-menu-item-content__arrow) {
  min-width: 0;
}

:deep(.n-menu-item-content-header) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

:deep(.n-menu-item-content--selected::before) {
  background: #eff6ff;
}

:deep(.n-menu-item-content--selected) {
  font-weight: 600;
}
</style>
