import auth from '@/plugins/auth';
import router, { constantRoutes, dynamicRoutes } from '@/router';
import { getMenus } from '@/api/menu';
import{ getMenuList } from './mock'
import Layout from '@/layout/index';
import ParentView from '@/components/ParentView';
import InnerLink from '@/layout/components/InnerLink';
import { startsWith, each, find, first, toLower } from 'lodash-es';

const THIRD_SERVICE_BASE_URL = process.env.VUE_APP_THIRD_BASE_URL;
const currentProBaseUrl = process.env.VUE_APP_SYS_BASE_URL;

const permission = {
  state: {
    routes: [],
    addRoutes: [],
    defaultRoutes: [],
    topbarRouters: [],
    sidebarRouters: constantRoutes || []
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes;
      state.routes = constantRoutes.concat(routes);
    },
    SET_DEFAULT_ROUTES: (state, routes) => {
      state.defaultRoutes = constantRoutes.concat(routes);
    },
    SET_TOPBAR_ROUTES: (state, routes) => {
      state.topbarRouters = routes;
    },
    SET_SIDEBAR_ROUTERS: (state, routes) => {
      state.sidebarRouters = routes;
    }
  },
  actions: {
    // 生成路由
    GenerateRoutes({ commit }) {
      return new Promise((resolve) => {
        // 向后端请求路由数据
          const menuDataList = recursionUpdateRouterPath([]);

          const sdata = JSON.parse(JSON.stringify(menuDataList));
          const rdata = JSON.parse(JSON.stringify(menuDataList));
          const sidebarRoutes = filterAsyncAllRouter(sdata);
          const rewriteRoutes = filterAsyncAllRouter(rdata, false, true);
          const asyncRoutes = filterDynamicRoutes(dynamicRoutes);

          const rootRoute = find(rewriteRoutes, { path: '/' });

          if (
            rootRoute &&
            (toLower(rootRoute.redirect) === 'noredirect' ||
              !rootRoute.redirect)
          ) {
            rootRoute.redirect = startsWith(rootRoute.children[0].path, '/')
              ? rootRoute.children[0].path
              : (rootRoute.path === '/' ? '/' : rootRoute.path + '/') +
                rootRoute.children[0].path;
          }

          if (!rootRoute) {
            const firstMenu = first(rewriteRoutes);
            if (firstMenu) {
              let redirectPath = firstMenu.path;

              if (
                firstMenu.children &&
                (toLower(firstMenu.redirect) === 'noredirect' ||
                  !firstMenu.redirect)
              ) {
                redirectPath = startsWith(firstMenu.children[0].path, '/')
                  ? firstMenu.children[0].path
                  : redirectPath + '/' + firstMenu.children[0].path;
              }

              rewriteRoutes.push({
                path: '/',
                redirect: redirectPath,
                hidden: true
              });
            }
          }

          rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true });
          router.addRoutes(asyncRoutes);
          commit('SET_ROUTES', rewriteRoutes);
          commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes));
          // commit('SET_SIDEBAR_ROUTERS', constantRoutes);
          // commit('SET_DEFAULT_ROUTES', sidebarRoutes);
          commit('SET_TOPBAR_ROUTES', sidebarRoutes);

          resolve(rewriteRoutes);
        });
    }
  }
};

function recursionUpdateRouterPath(asyncRouterMap, parentPath = '') {
  let routes = [];
  each(asyncRouterMap, (route) => {
    if (!startsWith(route.path, '/')) {
      route.path = (parentPath ? `${parentPath}/` : '') + route.path;
    }

    if (route.children != null && route.children && route.children.length) {
      route.children = recursionUpdateRouterPath(route.children, route.path);
    } else {
      delete route['children'];
      delete route['redirect'];
    }

    routes.push(route);
  });

  return routes;
}

function filterAsyncAllRouter(
  asyncRouterMap,
  lastRouter = false,
  type = false
) {
  let routes = [];
  each(asyncRouterMap, (route) => {
    // if (type && route.children) {
    //   if (!startsWith(route.path, currentProBaseUrl) && route.path !== '/') {
    //     route.children = filterThirdChildren(route.children);
    //   }
    // }

    if (
      !startsWith(route.path, currentProBaseUrl) &&
      route.path !== '/' &&
      lastRouter
    ) {
      route.meta.link = THIRD_SERVICE_BASE_URL + route.path;
      delete route.component;
    } else {
      if (route.component) {
        // Layout ParentView 组件特殊处理
        if (route.component === 'Layout') {
          route.component = Layout;
        } else if (route.component === 'ParentView') {
          route.component = ParentView;
        } else if (route.component === 'InnerLink') {
          route.component = InnerLink;
        } else {
          if (
            !startsWith(route.path, currentProBaseUrl) &&
            route.path !== '/'
          ) {
            delete route.component;
          } else {
            route.component = loadView(route.component);
          }
        }
      }

      if (startsWith(route.path, currentProBaseUrl)) {
        route.path = route.path.replace(currentProBaseUrl, '');
      }
    }

    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncAllRouter(route.children, route, type);
    } else {
      delete route['children'];
      delete route['redirect'];
    }

    routes.push(route);
  });

  return routes;
}

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncThirdRouter(asyncRouterMap) {
  const filerRouterMap = asyncRouterMap.filter((route) => {
    if (route.children) {
      route.children = filterThirdChildren(route.children, route);
    }

    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout;
      } else if (route.component === 'ParentView') {
        route.component = ParentView;
      } else if (route.component === 'InnerLink') {
        route.component = InnerLink;
      } else {
        delete route.component;
      }
    }

    return true;
  });

  return filerRouterMap;
}

function filterThirdChildren(childrenMap, lastRouter = false) {
  var children = [];
  childrenMap.forEach((el, index) => {
    if (el.children && el.children.length) {
      if (!lastRouter) {
        el.children.forEach((c) => {
          c.meta.link = THIRD_SERVICE_BASE_URL + c.path;
          if (c.children && c.children.length) {
            children = children.concat(filterThirdChildren(c.children, c));
            return;
          }

          delete c.component;
          children.push(c);
        });
        return;
      }
    }

    if (lastRouter) {
      el.meta.link = THIRD_SERVICE_BASE_URL + el.path;
    }

    delete el.component;
    children = children.concat(el);
  });

  return children;
}

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  return asyncRouterMap.filter((route) => {
    if (type && route.children) {
      route.children = filterChildren(route.children);
    }
    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout;
      } else if (route.component === 'ParentView') {
        route.component = ParentView;
      } else if (route.component === 'InnerLink') {
        route.component = InnerLink;
      } else {
        route.component = loadView(route.component);
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type);
    } else {
      delete route['children'];
      delete route['redirect'];
    }
    return true;
  });
}

function filterChildren(childrenMap, lastRouter = false) {
  var children = [];
  childrenMap.forEach((el, index) => {
    if (el.children && el.children.length) {
      if (el.component === 'ParentView' && !lastRouter) {
        el.children.forEach((c) => {
          // c.path = el.path + '/' + c.path;
          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c));
            return;
          }
          children.push(c);
        });
        return;
      }
    }
    // if (lastRouter) {
    //   el.path = lastRouter.path + '/' + el.path;
    // }
    children = children.concat(el);
  });
  return children;
}

// 动态路由遍历，验证是否具备权限
export function filterDynamicRoutes(routes) {
  const res = [];
  routes.forEach((route) => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route);
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route);
      }
    }
  });
  return res;
}

export const loadView = (view) => {
  if (process.env.NODE_ENV === 'development') {
    return (resolve) => require([`@/views/${view}`], resolve);
  } else {
    // 使用 import 实现生产环境的路由懒加载
    return () => import(`@/views/${view}`);
  }
};

export default permission;
