import { defineStore } from 'pinia'
import { ref } from 'vue'
import { constantRoutes } from '@/router/routes.js'

// Layout wrapper for authenticated pages
const Layout = () => import('@/layout/index.vue')

// Pre-scan all view components — Vite cannot resolve multi-level dynamic imports
const viewModules = import.meta.glob('@/views/**/*.vue')

function resolveComponent(comp) {
  // Try multiple key formats that import.meta.glob may produce
  const keys = [
    `/src/views/${comp}.vue`,
    `@/views/${comp}.vue`,
    `../views/${comp}.vue`
  ]
  for (const key of keys) {
    if (viewModules[key]) return viewModules[key]
  }
  // Fallback: search by suffix match
  const suffix = `/views/${comp}.vue`
  for (const [key, loader] of Object.entries(viewModules)) {
    if (key.endsWith(suffix)) return loader
  }
  console.warn(`[permission] View not found: ${comp}`)
  return undefined
}

/**
 * Convert a single server menu node to a vue-router route object.
 * Recursive — handles children at any depth.
 */
function menuToRoute(menu) {
  const route = {
    path: menu.path,
    name: menu.name || menu.path,
    meta: {
      title: menu.name,
      icon: menu.icon || '',
      id: menu.id,
      hidden: menu.visible === 0
    }
  }

  if (menu.component === 'Layout') {
    route.component = Layout
  } else if (menu.component) {
    const loader = resolveComponent(menu.component)
    if (loader) {
      route.component = loader
    }
  }

  if (menu.children && menu.children.length > 0) {
    route.children = menu.children.map(menuToRoute)
    // If this is a top-level layout node with children, add redirect
    if (!route.redirect && route.children.length > 0) {
      route.redirect = route.children[0].path
    }
  }

  return route
}

export const usePermissionStore = defineStore('permission', () => {
  const routes = ref([])
  const dynamicRoutes = ref([])

  /**
   * Generate vue-router routes from the server menu tree.
   * Returns the array of dynamic routes to be added via router.addRoute().
   */
  function generateRoutes(menus) {
    const generated = []

    // Wrap all menu roots under the Layout component
    const layoutRoute = {
      path: '/',
      name: 'Root',
      component: Layout,
      redirect: '/dashboard',
      children: []
    }

    // Flatten top-level menu items into Layout's children
    for (const menu of menus) {
      if (menu.children && menu.children.length > 0 && (!menu.component || menu.component === 'Layout')) {
        // Directory/group node — add its children directly under Layout
        for (const child of menu.children) {
          layoutRoute.children.push(menuToRoute(child))
        }
      } else if (menu.component) {
        // Leaf menu with a component — add as direct child
        layoutRoute.children.push(menuToRoute(menu))
      }
      // Skip menus without component and without children (empty directories)
    }

    // Always ensure dashboard is accessible
    const hasDashboard = layoutRoute.children.some(
      (r) => r.path === '/dashboard' || r.path === 'dashboard'
    )
    if (!hasDashboard) {
      layoutRoute.children.unshift({
        path: 'dashboard',
        name: 'Dashboard',
        component: resolveComponent('dashboard/index'),
        meta: { title: '工作台', icon: 'Odometer' }
      })
    }

    generated.push(layoutRoute)

    // Catch-all 404 — must be last
    generated.push({
      path: '/:pathMatch(.*)*',
      redirect: '/404',
      meta: { hidden: true }
    })

    dynamicRoutes.value = generated
    routes.value = [...constantRoutes, ...generated]

    return generated
  }

  function resetRoutes() {
    routes.value = []
    dynamicRoutes.value = []
  }

  return {
    routes,
    dynamicRoutes,
    generateRoutes,
    resetRoutes
  }
})
