import { constantRoutes } from '@/router'
import { getRouters } from '@/api/menu'

/**
 * 路由数据
 * @param item
 * @returns {{path, children: *[], meta: {icon, id, title}, name}}
 */
function getRoute(item) {
  // 路由基本格式
  const route = {
    // 路由的路径
    path: item.url,
    // 路由名
    name: item.label,
    meta: {
      id: item.id,
      title: item.label,
      icon: item.icon
    },
    // 路由的子路由
    children: []
  }
  if (item.url === 'layout') {
    route.component = resolve => (require([`@/layout`], resolve))
  } else {
    route.component = (resolve) => require([`@/views${item.url}`], resolve)
  }
  return route
}

/**
 * 菜单数据转换路由
 * @param menuList
 * @param routes
 * @returns {*[]}
 */
function dynamicMenuRoutes(menuList = [], routes = []) {
  // 用于保存普通路由数据
  const temp = []
  // 用于保存存在子路由的路由数据
  let route = []
  // 遍历数据
  for (let i = 0; i < menuList.length; i++) {
    // 存在子路由，则递归遍历，并返回数据作为 children 保存
    if (menuList[i].children && menuList[i].children.length > 0) {
      // 获取路由的基本格式
      route = getRoute(menuList[i])
      // 递归处理子路由数据，并返回，将其作为路由的 children 保存
      route.children = dynamicMenuRoutes(menuList[i].children)
      // 保存存在子路由的路由
      routes.push(route)
    } else {
      // 保存普通路由
      temp.push(getRoute(menuList[i]))
    }
  }
  return routes.concat(temp)
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  /**
   * 根据角色设置路由菜单
   * @param commit
   * @param roles
   * @returns {Promise<unknown>}
   */
  GenerateRoutes({ commit }, roles) {
    const roleIds = []
    roles.forEach(e => {
      roleIds.push(e.id)
    })
    return new Promise(resolve => {
      // 向后端请求路由数据
      getRouters(roleIds.join(',')).then(res => {
        const menuList = res.data.menuTree
        const accessedRoutes = dynamicMenuRoutes(menuList)
        accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
        commit('SET_ROUTES', accessedRoutes)
        resolve(accessedRoutes)
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
