import routerMap from '@/router/async/router.map'
import { mergeI18nFromRoutes } from '@/utils/i18n'
import Router from 'vue-router'
import deepMerge from 'deepmerge'
import { checkAuthorization } from '@/utils/request'

import basicOptions from '@/router/async/config.async'
import Cookies from "js-cookie";
import { api } from "@/services/index"
//应用配置
let appOptions = {
  router: undefined,
  i18n: undefined,
  store: undefined
}

/**
 * 设置应用配置
 * @param options
 */
function setAppOptions(options) {
  const { router, store, i18n } = options
  appOptions.router = router
  appOptions.store = store
  appOptions.i18n = i18n
}

/**
 * 根据 路由配置 和 路由组件注册 解析路由
 * @param routesConfig 路由配置
 * @param routerMap 本地路由组件注册配置
 */
function parseRoutes(routesConfig, routerMap) {
  let routes = []

  routesConfig.forEach(item => {
    // 获取注册在 routerMap 中的 router，初始化 routeCfg

    let router = undefined, routeCfg = {}
    if (typeof item === 'string') {
      router = routerMap[item]
      routeCfg = { path: (router && router.path) || item, router: item }
    } else if (typeof item === 'object') {
      router = routerMap
      routeCfg = item
    }


    if (!router) {
      console.warn(`can't find register for router ${routeCfg.router}, please register it in advance.`)
      router = typeof item === 'string' ? { path: item, name: item } : item
    }
    // 从 router 和 routeCfg 解析路由
    const meta = {
      authority: router.authority,
      icon: router.icon,
      page: router.page,
      link: router.link,
      params: router.params,
      query: router.query,
      ...router.meta
    }
    const cfgMeta = {
      authority: routeCfg.authority,
      icon: routeCfg.icon,
      page: routeCfg.page,
      link: routeCfg.link,
      params: routeCfg.params,
      query: routeCfg.query,
      ...routeCfg.meta
    }
    Object.keys(cfgMeta).forEach(key => {
      if (cfgMeta[key] === undefined || cfgMeta[key] === null || cfgMeta[key] === '') {
        delete cfgMeta[key]
      }
    })
    Object.assign(meta, cfgMeta)
    const route = {
      path: routeCfg.url || router.url || routeCfg.router,
      name: routeCfg.name || router.name,
      component: () => import(`@/pages/${routeCfg.url || router.url}`),
      redirect: routeCfg.redirect || router.redirect,
      meta: { ...meta, authority: meta.authority || '*' }
    }


    if (routeCfg.invisible || router.invisible) {
      route.meta.invisible = true
    }

    if (routeCfg.children && routeCfg.children.length > 0) {
      route.children = parseRoutes(routeCfg.children, routerMap)
    }
    routes.push(route)
  })
  return routes
}

/**
 * 加载路由
 * @param routesConfig {RouteConfig[]} 路由配置
 */
function loadRoutes(routesConfig) {
  //兼容 0.6.1 以下版本
  /*************** 兼容 version < v0.6.1 *****************/
  if (arguments.length > 0) {
    const arg0 = arguments[0]
    if (arg0.router || arg0.i18n || arg0.store) {
      routesConfig = arguments[1]
      console.error('the usage of signature loadRoutes({router, store, i18n}, routesConfig) is out of date, please use the new signature: loadRoutes(routesConfig).')
      console.error('方法签名 loadRoutes({router, store, i18n}, routesConfig) 的用法已过时, 请使用新的方法签名 loadRoutes(routesConfig)。')
    }
  }
  /*************** 兼容 version < v0.6.1 *****************/

  // 应用配置
  const { router, store, i18n } = appOptions

  // 如果 routesConfig 有值，则更新到本地，否则从本地获取
  if (routesConfig) {
    store.commit('account/setRoutesConfig', routesConfig)
  } else {
    routesConfig = store.getters['account/routesConfig']
  }
  // 如果开启了异步路由，则加载异步路由配置
  const asyncRoutes = store.state.setting.asyncRoutes
  if (asyncRoutes) {
    if (routesConfig && routesConfig.length > 0) {

      const routes = parseRoutes(routesConfig, routerMap)

      const finalRoutes = mergeRoutes(basicOptions.routes, routes)
      formatRoutes(finalRoutes)

      router.options = { ...router.options, routes: finalRoutes }
      router.matcher = new Router({ ...router.options, routes: [] }).matcher
      router.addRoutes(finalRoutes)
    }
  }
  // 提取路由国际化数据
  mergeI18nFromRoutes(i18n, router.options.routes)
  // 初始化Admin后台菜单数据
  const rootRoute = router.options.routes.find(item => item.path === '/')
  const menuRoutes = rootRoute && rootRoute.children
  if (menuRoutes) {
    store.commit('setting/setMenuData', menuRoutes)
  }
}

/**
 * 合并路由
 * @param target {Route[]}
 * @param source {Route[]}
 * @returns {Route[]}
 */
function mergeRoutes(target, source) {
  const routesMap = {}
  target.forEach(item => routesMap[item.path] = item)
  source.forEach(item => routesMap[item.path] = item)

  return Object.values(routesMap)
}

/**
 * 深度合并路由
 * @param target {Route[]}
 * @param source {Route[]}
 * @returns {Route[]}
 */
function deepMergeRoutes(target, source) {
  // 映射路由数组
  const mapRoutes = routes => {
    const routesMap = {}
    routes.forEach(item => {
      routesMap[item.path] = {
        ...item,
        children: item.children ? mapRoutes(item.children) : undefined
      }
    })
    return routesMap
  }
  const tarMap = mapRoutes(target)
  const srcMap = mapRoutes(source)

  // 合并路由
  const merge = deepMerge(tarMap, srcMap)

  // 转换为 routes 数组
  const parseRoutesMap = routesMap => {
    return Object.values(routesMap).map(item => {
      if (item.children) {
        item.children = parseRoutesMap(item.children)
      } else {
        delete item.children
      }
      return item
    })
  }
  return parseRoutesMap(merge)
}

/**
 * 格式化路由
 * @param routes 路由配置
 */
function formatRoutes(routes) {

  routes.forEach(route => {
    const { path } = route

    if (!path?.startsWith('/') && path !== '*') {
      route.path = '/' + path
    }
  })
  formatAuthority(routes)
}

/**
 * 格式化路由的权限配置
 * @param routes 路由
 * @param pAuthorities 父级路由权限配置集合
 */
function formatAuthority(routes, pAuthorities = []) {
  routes.forEach(route => {
    const meta = route.meta
    const defaultAuthority = pAuthorities[pAuthorities.length - 1] || { permission: '*' }
    if (meta) {
      let authority = {}
      if (!meta.authority) {
        authority = defaultAuthority
      } else if (typeof meta.authority === 'string') {
        authority.permission = meta.authority
      } else if (typeof meta.authority === 'object') {
        authority = meta.authority
        const { role } = authority
        if (typeof role === 'string') {
          authority.role = [role]
        }
        if (!authority.permission && !authority.role) {
          authority = defaultAuthority
        }
      }
      meta.authority = authority
    } else {
      const authority = defaultAuthority
      route.meta = { authority }
    }
    route.meta.pAuthorities = pAuthorities
    if (route.children) {
      formatAuthority(route.children, [...pAuthorities, route.meta.authority])
    }
  })
}

/**
 * 从路由 path 解析 i18n key
 * @param path
 * @returns {*}
 */
function getI18nKey(path) {
  console.log(path)
  if (path) {
    const keys = path.split('/').filter(item => !item.startsWith(':') && item != '')
    keys.push('name')
    return keys.join('.')
  } else {
    return ''
  }


}

// function clearQueryParams() {
//   const { router } = appOptions
//   const currentPath = window.location.pathname;
//   router.replace({ path: currentPath, query: {} });
// }


/**
 * 加载导航守卫
 * @param guards
 * @param options
 */
function loadGuards(guards, options) {
  const { beforeEach, afterEach } = guards
  const { router } = options


  api.userService.getLoginUser().then((response) => {

    if (response.data.code == 200) {
      //头像地址拼接
      if (
        response.data.data.headSculpture != "" &&
        response.data.data.headSculpture != null &&
        response.data.data.headSculpture != undefined
      ) {
        response.data.data.headSculpture =
          process.env.BASE_URL + response.data.data.headSculpture;
      }
      localStorage.setItem("user_data", JSON.stringify(response.data.data));

      sessionStorage.setItem("user", response.data.data.id);
      Cookies.set("user", response.data.data.id);
      localStorage.setItem("routerId", "420");

    }
  });

  beforeEach.forEach(guard => {
    let userName = Cookies.get('user')
    if (guard && typeof guard === 'function') {
      router.beforeEach((to, from, next) => {

        guard(to, from, next, options)
        if (from.meta && from.meta.destroyOnClose) {
          // 当前组件需要在离开时销毁
          // 这里可以添加确认提示等逻辑
          // 假设我们不需要确认，直接销毁
          from.matched[0].instances.default.$destroy()
        }

        if (checkAuthorization()) {
          //
          addDynamicMenuAndRoutes(userName, to, from)
        }

        // console.log('beforeEach', guard)
        // if(to.meta ){
        //   if(to.meta.hidden==false){
        //     //
        //     // guard(to, from, next, options)

        //   }else{
        //     guard(to, from, next, options)

        //   }
        // }else{
        //   guard(to, from, next, options)

        // }
      })
    }

  })
  afterEach.forEach(guard => {
    if (guard && typeof guard === 'function') {
      router.afterEach((to, from) => guard(to, from, options))
    }
  })
}
/**
* 加载动态菜单和路由
*/
function addDynamicMenuAndRoutes(userName,) {
  // 处理IFrame嵌套页面
  const { router, store, } = appOptions
  // handleIFrameUrl(to.path)

  if (store.state.app.menuRouteLoaded) {

    return
  }
  api.sysManage.getMenuList({ 'userName': userName }).then(res => {
    // 添加动态路由
    console.log(res.data.data)
    let dynamicRoutes = addDynamicRoutes(res.data.data)
    // console.log(res)
    // 处理静态组件绑定路由
    handleStaticComponent(router, dynamicRoutes)
    router.addRoutes(router.options.routes)
    // 保存加载状态
    store.commit('menuRouteLoaded', true)
    // 保存菜单树
    // store.commit('setNavTree', res.data.data)
  }).then(() => {
    // api.user.findPermissions({ 'name': userName }).then(res => {
    //   // 保存用户权限标识集合
    //   store.commit('setPerms', res.data)
    // })
  })
}
/**
 * 处理路由到本地直接指定页面组件的情况
 * 比如'代码生成'是要求直接绑定到'Generator'页面组件
 */
function handleStaticComponent(router, dynamicRoutes) {
  for (let j = 0; j < dynamicRoutes.length; j++) {
    if (dynamicRoutes[j].name == '代码生成') {
      dynamicRoutes[j].component = ''
      break
    }
  }
  // console.log(router.options.routes[0], dynamicRoutes)
  // router.options.routes[0].children = router.options.routes[0]?.children.concat(dynamicRoutes)
}

/**
* 添加动态(菜单)路由
* @param {*} menuList 菜单列表
* @param {*} routes 递归创建的动态(菜单)路由
*/
function addDynamicRoutes(menuList = [], routes = []) {

  var temp = []
  for (var i = 0; i < menuList.length; i++) {
    if (menuList[i].children && menuList[i].children.length >= 1) {
      temp = temp.concat(menuList[i].children)
    } else if (menuList[i].url && /\S/.test(menuList[i].url)) {
      menuList[i].url = menuList[i].url.replace(/^\//, '')
      // 创建路由配置
      var route = {
        path: menuList[i].url,
        component: null,
        name: menuList[i].name,
        meta: {
          icon: menuList[i].icon,
          index: menuList[i].id
        }
      }


      try {
        // 根据菜单URL动态加载vue组件，这里要求vue组件须按照url路径存储
        // 如url="sys/user"，则组件路径应是"@/views/sys/user.vue",否则组件加载不到
        let array = menuList[i].url.split('/')
        let url = ''
        for (let i = 0; i < array.length; i++) {
          url += array[i].substring(0, 1).toUpperCase() + array[i].substring(1) + '/'
        }
        url = url.substring(0, url.length - 1)
        route['component'] = resolve => require([`@/pages/${url}`], resolve)
      } catch (e) {
        //
      }


      routes.push(route)
    }
  }
  if (temp.length >= 1) {
    addDynamicRoutes(temp, routes)
  } else {
    //
  }

  return routes
}


export { parseRoutes, loadRoutes, formatAuthority, getI18nKey, loadGuards, deepMergeRoutes, formatRoutes, setAppOptions }
