<template>
  <n-menu
    :collapsed="authStore.layoutCollapsed"
    :collapsed-width="84"
    :collapsed-icon-size="18"
    :options="menuOptions"
    :value="activePath"
    :indent="16"
    @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 || menu.type === 'BUTTON') return null

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

  const key = menu.path && menu.type !== 'CATALOG' ? 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) {
  height: 100%;
  min-height: 0;
  overflow-x: hidden;
  overflow-y: auto;
  font-size: 13px;
  background: transparent;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

:deep(.n-menu::-webkit-scrollbar) {
  display: none;
}

:deep(.n-menu-content),
:deep(.n-menu-content-wrapper) {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

:deep(.n-menu-content::-webkit-scrollbar),
:deep(.n-menu-content-wrapper::-webkit-scrollbar) {
  display: none;
}

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

:deep(.n-menu-item-content),
:deep(.n-submenu .n-menu-item-content-header) {
  transition:
    background 0.16s ease,
    color 0.16s 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) {
  font-weight: 600;
  box-shadow: none;
}

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

:deep(.n-menu--collapsed .n-menu-item-content),
:deep(.n-menu--collapsed .n-submenu .n-menu-item-content-header) {
  justify-content: center;
  padding-left: 0 !important;
  padding-right: 0 !important;
}

:deep(.n-menu--collapsed .n-menu-item-content__icon),
:deep(.n-menu--collapsed .n-submenu .n-menu-item-content-header__icon) {
  margin-right: 0 !important;
  width: 100%;
  display: flex;
  justify-content: center;
}

:deep(.n-menu-item-content__icon .n-icon),
:deep(.n-menu-item-content-header__icon .n-icon) {
  font-size: 18px;
}
</style>
