import router, { asyncRoutes } from '@/router'
import settings from './settings'
import { getToken, setToken, TokenKey } from '@/utils/auth'
import NProgress from 'nprogress'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
import 'nprogress/nprogress.css'
import getPageTitle from '@/utils/getPageTitle'
import { RouterRowTy } from '~/router'
import { useUserStore } from '@/store/user'
import { usePermissionStore } from '@/store/permission'
import Layout from '@/layout'
import { setTree } from '@/utils/validate'
import * as _ from 'lodash'
const whiteList = ['/login', '/404', '/401'] // no redirect whitelist
router.beforeEach(async (to: any, from, next: any) => {
  // start progress bar
  if (settings.isNeedNprogress) NProgress.start()
  // set page title
  document.title = getPageTitle(to.meta.title)
  if (!settings.isNeedLogin) setToken(TokenKey, settings.tmpToken)
  const hasToken: string | null = getToken(TokenKey)

  const userStore = useUserStore()
  const permissionStore = usePermissionStore()
  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
    } else {
      //judge isGetUserInfo
      const isGetUserInfo: boolean = permissionStore.isGetUserInfo
      if (isGetUserInfo) {
        next()
      } else {
        try {
          let accessRoutes: any = []
          if (settings.isNeedLogin) {
            // get user info
            // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
            await userStore.getInfo()
            const treeData: any = await userStore.getMenuInfo()
            const treeMenu = setTree(treeData, 'up_auth_id', 'auth_id')
            const dataMenu = _.unionBy(treeMenu, 'auth_id')
            const menus = parseMenu(dataMenu)
            console.log(menus)
            // const { roles }: any = await userStore.getInfo()
            // accessRoutes = await permissionStore.generateRoutes(roles)
            accessRoutes = menus
          } else {
            accessRoutes = asyncRoutes
          }
          // setting constRouters and accessRoutes to vuex , in order to sideBar for using
          permissionStore.M_routes(accessRoutes)
          // dynamically add accessible routes
          //router4 addRoutes destroyed
          accessRoutes.forEach((route: RouterRowTy) => {
            router.addRoute(route)
          })
          //already get userInfo
          permissionStore.M_isGetUserInfo(true)
          // hack method to ensure that addRoutes is complete
          // set the replace: true, so the navigation will not leave a history record
          next({ ...to, replace: true })
        } catch (err) {
          console.log(err)
          await userStore.resetState()
          next(`/login?redirect=${to.path}`)
          if (settings.isNeedNprogress) NProgress.done()
        }
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      next()
    } else {
      next(`/login?redirect=${to.path}`)
      if (settings.isNeedNprogress) NProgress.done()
    }
  }
})

function parseItem(item) {
  const menus: any = []
  if (!item.children) {
    menus.push({
      path: item.route_info,
      component: Layout,
      name: item.auth_ident,
      meta: {
        title: item.auth_name,
        elSvgIcon: item.show_icon ?? 'Fold',
        show_index: item.show_index,
        qid: item.queryTemplateID,
      },
    })
  } else if (item.children && item.children.length <= 1) {
    menus.push({
      path: item.route_info,
      component: Layout,
      name: item.auth_ident,
      meta: {
        title: item.auth_name,
        elSvgIcon: item.show_icon ?? 'Fold',
        show_index: item.show_index,
        qid: item.queryTemplateID,
      },
      children: [
        {
          path: item.route_info,
          component: () => import('./views' + item.file_link),
          name: item.auth_ident,
          meta: {
            title: item.auth_name,
            elSvgIcon: item.show_icon ?? 'Fold',
            show_index: item.show_index,
            qid: item.queryTemplateID,
          },
        },
      ],
    })
  } else {
    const datas = item.children
    const arrs: any = []
    datas.forEach((item, ci) => {
      arrs.push({
        path: item.route_info,
        component: () => import('./views' + item.file_link),
        name: item.auth_ident + ci,
        meta: {
          title: item.auth_name,
        },
      })
    })
    menus.push({
      path: item.route_info,
      component: Layout,
      name: item.auth_ident,
      meta: {
        show_index: item.show_index,
        qid: item.queryTemplateID,
        title: item.auth_name,
        elSvgIcon: item.show_icon ?? 'Fold',
      },
      children: arrs,
      // children: [
      //   {
      //     path: item.route_info,
      //     component: {
      //       render: () => h(resolveComponent('router-view')),
      //     },
      //     name: item.auth_ident,
      //     redirect: arrs[0].path,
      //     meta: {
      //       title: item.auth_name,
      //       elSvgIcon: 'Fold',
      //     },
      //     children: arrs,
      //   },
      // ],
    })
  }
  return menus
}

function parseMenu(arr: Array<any>) {
  const menus: any = []
  arr.forEach((item) => {
    if (item.show_type == 1) {
      const res = parseItem(item)
      menus.push(res)
    } else if (item.show_type == 2) {
      const res = parseItem(item)
      menus.push(res)
    }
  })
  const newMenus = menus.flat()
  newMenus.push({
    path: '/userManagement',
    component: Layout,
    name: 'UserManagement',
    redirect: '/userManagement/permission',
    //using el svg icon, the elSvgIcon first when at the same time using elSvgIcon and icon
    meta: { title: '权限管理', elSvgIcon: 'Avatar', show_index: 2 },
    children: [
      {
        path: '/userManagement/permission',
        name: 'Permission',
        meta: { title: '权限项管理', elSvgIcon: 'Avatar' },
        component: () => import('@/views/userManagement/permission/index.vue'),
      },
    ],
  })
  const allMenus = newMenus.length
    ? newMenus.sort((a, b) => a.meta.show_index - b.meta.show_index)
    : []
  allMenus.push({
    path: '/:pathMatch(.*)',
    redirect: '/404',
    hidden: true,
  })
  allMenus[0].redirect = allMenus[0].path
  allMenus[0].path = '/'
  return allMenus
}

router.afterEach(() => {
  if (settings.isNeedNprogress) NProgress.done()
})
