import { createRouter, createWebHistory } from 'vue-router'
import cookie from 'vue-cookies'
import { isURL } from '@/utils/validate'
import { clearLoginInfo } from '@/utils'
import Layout from '@/layout/main.vue'
import Login from '@/views/common/login/index.vue'

// 定义全局路由（无需嵌套在左右整体布局中）
const globalRoutes = [
  {
    path: '/404', // 404 页面路径
    component: () => import('@/views/common/error-page/404.vue'), // 动态导入 404 页面组件
    name: '404', // 路由名称
    meta: { title: '404未找到' } // 元信息，用于设置页面标题等
  },
  {
    path: '/login', // 登录页面路径
    component: Login, // 登录页面组件
    name: 'login', // 路由名称
    meta: { title: '登录' } // 元信息，用于设置页面标题等
  }
]

// 定义主路由（需要嵌套在 Layout 组件中）
export const mainRoutes = {
  path: '/', // 根路径
  component: Layout, // 布局组件
  name: 'home', // 路由名称
  redirect: '/home', // 默认重定向到 home 页面
  children: [ // 子路由
    {
      path: 'home', // 主页路径
      name: 'home', // 路由名称
      component: () => import('@/views/common/home/index.vue') // 动态导入主页组件
    },
    {
      path: '/prodInfo', // 产品信息页面路径
      name: 'prodInfo', // 路由名称
      component: () => import('@/views/modules/prod/prodInfo/index.vue') // 动态导入产品信息页面组件
    }
  ],
  beforeEnter (to, from, next) { // 路由守卫，检查用户是否已登录
    const authorization = cookie.get('Authorization') // 获取存储在 cookie 中的授权信息
    if (!authorization || !/\S/.test(authorization)) { // 如果没有授权信息或为空
      clearLoginInfo() // 清除登录信息
      next({ name: 'login' }) // 重定向到登录页面
    }
    next() // 否则继续导航
  }
}

// 创建 Vue Router 实例
const router = createRouter({
  history: createWebHistory(), // 使用 HTML5 History 模式
  scrollBehavior: () => ({ top: 0 }), // 设置滚动行为，每次导航回到顶部
  isAddDynamicMenuRoutes: false, // 是否已经添加动态(菜单)路由
  routes: globalRoutes.concat(mainRoutes) // 合并全局路由和主路由
})

// 全局前置守卫，拦截所有路由导航
router.beforeEach((to, from, next) => {
  const commonStore = useCommonStore() // 初始化 Vuex store 实例

  // 添加动态(菜单)路由逻辑
  if (router.options.isAddDynamicMenuRoutes || fnCurrentRouteType(to, globalRoutes) === 'global') {
    // 已经添加动态路由或访问的是全局路由，直接处理导航
    const routeList = commonStore.routeList // 获取路由列表
    let navTitles = [] // 用于存储导航标题
    let leftMenuId = '' // 用于存储左侧菜单 ID

    // 查找当前路由对应的菜单项，并构建导航标题链
    routeList.forEach(item => {
      if (to.meta.menuId === item.menuId) {
        navTitles.push(item.name)
        routeList.forEach(item1 => {
          if (item.parentId === item1.menuId) {
            navTitles.push(item1.name)
            leftMenuId = item.parentId
            routeList.forEach(item2 => {
              if (item1.parentId === item2.menuId) {
                navTitles.push(item2.name)
                leftMenuId = item1.parentId
              }
            })
          }
        })
      }
    })

    navTitles = navTitles.reverse() // 反转导航标题链

    // 更新 Vuex store 中的状态
    if (to.meta.isLeftMenu || to.path === '/home' || leftMenuId) {
      if (leftMenuId) {
        commonStore.updateSelectLeftId(leftMenuId) // 更新选中的左侧菜单 ID
        commonStore.updateSelectRightId(to.meta.menuId) // 更新选中的右侧菜单 ID
      } else {
        commonStore.updateSidebarFold(true) // 折叠侧边栏
        commonStore.updateSelectLeftId(to.path === '/home' ? '' : to.meta.menuId) // 更新选中的左侧菜单 ID
      }
    }

    commonStore.updateSelectMenu(navTitles) // 更新选中的菜单标题链
    next() // 继续导航
  } else {
    // 请求菜单列表和权限信息
    http({
      url: http.adornUrl('/sys/menu/nav'), // 请求 URL
      method: 'get', // 请求方法
      params: http.adornParams() // 请求参数
    }).then(({ data }) => {
      sessionStorage.setItem('Authorities', JSON.stringify(data.authorities || '[]')) // 存储权限信息到 sessionStorage
      fnAddDynamicMenuRoutes(data.menuList) // 添加动态路由
      router.options.isAddDynamicMenuRoutes = true // 标记动态路由已添加

      // 构建完整的路由列表，并保存到 Vuex store 和 sessionStorage
      const rList = []
      data.menuList.forEach(item => {
        item.isLeftMenu = item.parentId === 0 // 判断是否为左侧菜单
        rList.push({
          menuId: item.menuId,
          name: item.name,
          parentId: item.parentId,
          url: item.url
        })
        if (item.list) {
          item.list.forEach(item1 => {
            item1.isLeftMenu = item1.parentId === 0
            rList.push({
              menuId: item1.menuId,
              name: item1.name,
              parentId: item1.parentId,
              url: item1.url
            })
            if (item1.list) {
              item1.list.forEach(item2 => {
                item2.isLeftMenu = item2.parentId === 0
                rList.push({
                  menuId: item2.menuId,
                  name: item2.name,
                  parentId: item2.parentId,
                  url: item2.url
                })
              })
            }
          })
        }
      })

      fnAddDynamicMenuRoutes(data.menuList) // 再次调用以确保所有子菜单被正确添加
      sessionStorage.setItem('menuList', JSON.stringify(data.menuList || '[]')) // 存储菜单列表到 sessionStorage
      commonStore.updateRouteList(rList) // 更新 Vuex store 中的路由列表
      commonStore.updateMenuIds(rList) // 更新 Vuex store 中的菜单 ID 列表

      // 重新导航到目标页面
      next({ ...to, replace: true })
    }).catch(e => {
      console.log(`%c${e} 请求菜单列表和权限失败，跳转至登录页！！`, 'color:blue') // 打印错误信息
      router.push({ name: 'login' }) // 跳转到登录页面
    })
  }
})

/**
 * 判断当前路由类型，返回 'global' 或 'main'
 * @param {*} route 当前路由对象
 * @param globalRoutes 全局路由数组
 */
function fnCurrentRouteType (route, globalRoutes = []) {
  let temp = [] // 临时存储子路由
  for (let i = 0; i < globalRoutes.length; i++) {
    if (route.path === globalRoutes[i].path) {
      return 'global' // 如果匹配到全局路由，返回 'global'
    } else if (globalRoutes[i].children && globalRoutes[i].children.length >= 1) {
      temp = temp.concat(globalRoutes[i].children) // 将子路由添加到临时数组
    }
  }
  return temp.length >= 1 ? fnCurrentRouteType(route, temp) : 'main' // 递归查找子路由，直到找到匹配项或返回 'main'
}

/**
 * 添加动态(菜单)路由
 * @param {*} menuList 菜单列表
 * @param {*} routes 递归创建的动态(菜单)路由数组
 */
function fnAddDynamicMenuRoutes (menuList = [], routes = []) {
  let temp = [] // 临时存储子菜单项
  const modules = import.meta.glob('../views/modules/**/index.vue') // 动态导入视图模块

  // 遍历菜单列表，创建对应的路由对象
  for (let i = 0; i < menuList.length; i++) {
    if (menuList[i].list && menuList[i].list.length >= 1) {
      temp = temp.concat(menuList[i].list) // 如果有子菜单，添加到临时数组
    } else if (menuList[i].url && /\S/.test(menuList[i].url)) {
      menuList[i].url = menuList[i].url.replace(/^\//, '') // 移除 URL 开头的斜杠
      const route = {
        path: menuList[i].url, // 路径
        component: null, // 组件
        name: menuList[i].url, // 名称
        meta: {
          menuId: menuList[i].menuId, // 菜单项 ID
          title: menuList[i].name, // 标题
          isDynamic: true, // 标记为动态路由
          isTab: true, // 标记为标签页
          iframeUrl: '' // iframe URL，默认为空
        }
      }

      // 如果 URL 是有效的 HTTP[S] 地址，则通过 iframe 展示
      if (isURL(menuList[i].url)) {
        route.path = `i-${menuList[i].menuId}` // 修改路径为 iframe 特定格式
        route.name = `i-${menuList[i].menuId}` // 修改名称为 iframe 特定格式
        route.meta.iframeUrl = menuList[i].url // 设置 iframe URL
      } else {
        try {
          route.component = modules[`../views/modules/${menuList[i].url}/index.vue`] || null // 动态加载组件
        } catch (e) {}
      }

      routes.push(route) // 将路由对象添加到 routes 数组
    }
  }

  // 如果还有子菜单项，递归处理
  if (temp.length >= 1) {
    fnAddDynamicMenuRoutes(temp, routes)
  } else {
    mainRoutes.name = 'main-dynamic' // 修改主路由名称为 'main-dynamic'
    mainRoutes.children = routes // 将动态路由添加为主路由的子路由
    router.addRoute(mainRoutes) // 添加主路由到 Vue Router 实例
  }

  // 添加一个通配符路由，处理未匹配的路径，重定向到 404 页面
  router.addRoute({ path: '/:pathMatch(.*)*', redirect: { name: '404' } })
}

export default router // 导出配置好的 Vue Router 实例
