import type { RouteRecordRaw } from 'vue-router'
import type { MenuItem } from '@/types/menu'

// Vite glob 懒加载所有视图组件
// 注意：此文件位于 src/utils/，../views 指向 src/views
const viewModules = import.meta.glob('../views/**/*.vue')

/**
 * 根据字符串路径懒加载 Vue 组件
 * @param componentPath - 如 'dashboard/index' 或 'system/user/index'
 */
export function loadComponent(componentPath: string): () => Promise<unknown> {
  const key = `../views/${componentPath}.vue`
  if (viewModules[key]) {
    return viewModules[key] as () => Promise<unknown>
  }
  console.warn(`[路由] 未找到组件: ${key}`)
  return () => import('../views/error/404.vue')
}

/**
 * 路径拼接（兼容绝对路径与相对路径）
 */
export function resolvePath(basePath: string, routePath: string): string {
  if (routePath.startsWith('/')) return routePath
  return `${basePath}/${routePath}`.replace(/\/+/g, '/')
}

/**
 * 将嵌套菜单数据扁平化为 Vue Router 可用的路由配置
 * 所有动态路由最终挂载在 Root（Layout）下
 */
export function flattenMenuToRoutes(menuItems: MenuItem[], parentPath = ''): RouteRecordRaw[] {
  const routes: RouteRecordRaw[] = []

  menuItems.forEach(item => {
    const fullPath = resolvePath(parentPath, item.path)

    // 过滤掉 hidden 的子菜单
    const visibleChildren = item.children?.filter(child => !child.meta?.hidden) || []

    if (visibleChildren.length > 0) {
      // 父级菜单：注册 redirect 路由，再递归处理子项
      routes.push({
        path: fullPath,
        redirect: item.redirect || resolvePath(fullPath, visibleChildren[0].path),
        meta: item.meta
      } as RouteRecordRaw)
      routes.push(...flattenMenuToRoutes(visibleChildren, fullPath))
    } else if (item.children && item.children.length > 0) {
      // 有子菜单但都是隐藏的：注册父级路由 + 递归处理隐藏子项
      routes.push({
        path: fullPath,
        name: item.name,
        component: loadComponent(item.component!),
        meta: item.meta
      } as RouteRecordRaw)
      routes.push(...flattenMenuToRoutes(item.children, fullPath))
    } else {
      // 叶子路由：直接对应一个页面组件
      routes.push({
        path: fullPath,
        name: item.name,
        component: loadComponent(item.component!),
        meta: item.meta
      } as RouteRecordRaw)
    }
  })

  return routes
}
