import type { RouteRecordRaw } from 'vue-router';
import { isNavigationFailure, Router } from 'vue-router';
import { useUserStoreWidthOut } from '@/store/modules/user';
import { useAsyncRouteStoreWidthOut } from '@/store/modules/asyncRoute';
import { ACCESS_TOKEN } from '@/store/mutation-types';
import { storage } from '@/utils/Storage';
import { PageEnum } from '@/enums/pageEnum';
import { ErrorPageRoute } from '@/router/base';
import NProgress from 'nprogress';
import { ElMessage } from 'element-plus';
import { getRedirectUrl } from '@/utils/getRedirectUrl';

const LOGIN_PATH = PageEnum.BASE_LOGIN;

const whitePathList = [LOGIN_PATH, PageEnum.ROOT, PageEnum.BASE_HOME, PageEnum.C_BRAIN_ENTRY]; // no redirect whitelist

const setDynamicRoute = async (router) => {
  const userStore = useUserStoreWidthOut();
  const asyncRouteStore = useAsyncRouteStoreWidthOut();
  let userInfo;
  userInfo = await userStore.GetInfo();
  const routes = await asyncRouteStore.generateRoutes(userInfo);
  // 动态添加可访问路由表
  routes.forEach((item) => {
    router.addRoute(item as unknown as RouteRecordRaw);
  });
  //添加404
  const isErrorPage = router.getRoutes().findIndex((item) => item.name === ErrorPageRoute.name);
  if (isErrorPage === -1) {
    router.addRoute(ErrorPageRoute as unknown as RouteRecordRaw);
  }
  asyncRouteStore.setDynamicAddedRoute(true);
};

export function createRouterGuards(router: Router) {
  const userStore = useUserStoreWidthOut();
  const asyncRouteStore = useAsyncRouteStoreWidthOut();
  router.beforeEach(async (to, from, next) => {
    NProgress.start();
    if (from.path === LOGIN_PATH && to.name === 'errorPage') {
      next(PageEnum.BASE_HOME);
      return;
    }
    const token = storage.get(ACCESS_TOKEN);

    // Whitelist can be directly entered
    if (whitePathList.includes(to.path as PageEnum)) {
      if (token && !asyncRouteStore.getIsDynamicAddedRoute) {
        try {
          await setDynamicRoute(router);
        } catch {
          console.log('设置路由失败');
          // next({ name: 'HomePage' });
        }
      }
      next();
      return;
    }

    if (!token) {
      // You can access without permissions. You need to set the routing meta.ignoreAuth to true
      if (to.meta.ignoreAuth) {
        next();
        return;
      }
      // redirect login page
      // 这里登录要改造
      const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
        path: LOGIN_PATH,
        replace: true,
      };
      if (to.path) {
        redirectData.query = {
          ...redirectData.query,
          redirect: to.path,
        };
      }
      // ElMessage.error('请先登录2');
      userStore.showLogin = true;
      next({ name: 'HomePage' });
      return;
    }

    if (asyncRouteStore.getIsDynamicAddedRoute) {
      next();
      return;
    }
    try {
      await setDynamicRoute(router);
    } catch (err) {
      userStore.showLogin = true;
      next({ name: 'HomePage' });
      return;
    }
    NProgress.done();
    const redirectPath = (from.query.redirect || to.path) as string;
    const redirect = decodeURIComponent(redirectPath);
    const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
    next(nextData);
  });

  router.afterEach((to, _, failure) => {
    //handleKeepAlive(to);
    document.title =
      (to?.meta?.documentTitle ? to?.meta?.documentTitle : (to?.meta?.title as string)) || document.title;
    if (isNavigationFailure(failure)) {
      //console.log('failed navigation', failure)
    }
    const asyncRouteStore = useAsyncRouteStoreWidthOut();
    // 在这里设置需要缓存的组件名称
    const keepAliveComponents = asyncRouteStore.keepAliveComponents;
    const currentComName: any = to.matched.find((item) => item.name == to.name)?.name;
    if (currentComName && !keepAliveComponents.includes(currentComName) && to.meta?.keepAlive) {
      // 需要缓存的组件
      keepAliveComponents.push(currentComName);
    } else if (!to.meta?.keepAlive || to.name == 'Redirect') {
      // 不需要缓存的组件
      const index = asyncRouteStore.keepAliveComponents.findIndex((name) => name == currentComName);
      if (index != -1) {
        keepAliveComponents.splice(index, 1);
      }
    }
    asyncRouteStore.setKeepAliveComponents(keepAliveComponents);
    NProgress.done();
  });
}
