import type {
  ComponentRecordType,
  GenerateMenuAndRoutesOptions,
} from '@vben/types';

import { generateAccessible } from '@vben/access';
import { preferences } from '@vben/preferences';

import { message } from 'ant-design-vue';
import { useUserStore } from '@vben/stores';

import { BasicLayout, IFrameView } from '#/layouts';
import { $t } from '#/locales';
import { useAuthStore } from '#/store';
import type { RouteRecordRaw } from 'vue-router';
import { accessRoutes } from './routes';

const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');

/**
 * 从accessRoutes中根据路径获取可访问的路由
 * @param paths 路径列表
 * @returns 可访问的路由列表
 */
async function getAccessRoutersByPathAndAuth(paths: string[]) {
  const routes = filterAccessRoutes(accessRoutes, paths);
  console.log('routes', routes);
  return routes;
}

/**
 * 从路由列表中根据路径过滤可访问的路由
 * 逻辑：
 * 1. 递归遍历路由列表，判断路由的路径或名称是否在路径列表中
 * 2. 如果路由的路径或名称在路径列表中，将路由添加到可访问的路由列表中
 * 3. 如果路由有子路由，递归调用本函数处理子路由
 * @param routes 路由列表
 * @param paths 路径列表
 * @returns 可访问的路由列表
 */
function filterAccessRoutes(routes: RouteRecordRaw[], paths: string[]) {
  const accessRoutes :any = [];
  routes.forEach((route) => {
    //构建route的新的路由对象，设置到accessRoutes的必须是一个全新的对象，因为需要判断其子路由是否能被添加到当前route下
    const newRoute = { ...route };
    //重建子路由
    newRoute.children =  [];
    if (route.children) {
      newRoute.children.push(...filterAccessRoutes(route.children, paths));
    }

    if (!(route.meta?.fixed || newRoute.children?.length > 0 ||paths.includes(route.path || '') || paths.includes(route.name || '') )) {
      return;
    }
    //component路径处理，需要把component路径处理为字符串
    if (typeof newRoute.component === 'function') {
      newRoute.component = newRoute.component.toString();
    }else{
      newRoute.component = newRoute.component as string || '';
    }
    console.log('newRoute.component', newRoute.component);
    newRoute.component = newRoute.meta.path;
    //加入路由
    accessRoutes.push(newRoute);
  });
  return accessRoutes;
}

/**
 * 从后端获取路由
 * @returns 路由列表
 */
async function getRoutersByBackend(){
  const userStore = useUserStore();
  const authStore = useAuthStore();
  const userInfo = userStore.userInfo || (await authStore.fetchUserInfo());
  console.log('userInfo', userInfo);
  //测试'/system/user'，/system
  // return await getAccessRoutersByPathAndAuth(['/system/user', '/system' ,'/dashboard' ,'/analytics']);
  //正式，根据用户菜单获取可访问路由
  return await getAccessRoutersByPathAndAuth(userInfo.menus);
}

async function generateAccess(options: GenerateMenuAndRoutesOptions) {
  const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');

  const layoutMap: ComponentRecordType = {
    BasicLayout,
    IFrameView,
  };
  //路由控制
  const accessMode = 'backend'|| preferences.app.accessMode;
  // const accessMode = preferences.app.accessMode;
  return await generateAccessible(accessMode, {
    ...options,
    fetchMenuListAsync: async () => {
      message.loading({
        content: `${$t('common.loadingMenu')}...`,
        duration: 1.5,
      });
      // 从后端获取路由
      return await getRoutersByBackend();
    },
    // 可以指定没有权限跳转403页面
    forbiddenComponent,
    // 如果 route.meta.menuVisibleWithForbidden = true
    layoutMap,
    pageMap,
  });
}

export { generateAccess };
