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

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

import { message } from 'ant-design-vue';

import { getAllMenusApi } from '#/api';
import { BasicLayout, IFrameView } from '#/layouts';

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

/**
 * 后台路由转vben路由
 * @param menuList 后台菜单
 * @param parentPath 上级目录
 * @returns vben路由
 */
function backMenuToVbenMenu(
  routes: RouteRecordRaw[],
  menuList: Set<string>,
): RouteRecordStringComponent[] {
  const resultList: RouteRecordStringComponent[] = [];
  for (const route of routes) {
    if (!hasPermission(menuList, route)) {
      continue;
    }

    const { component, children, meta } = route;

    let componentPath = '';
    // 如果是动态组件或异步加载函数，可以提取路径字符串
    if (typeof component === 'function') {
      try {
        // 获取 () => import('xxx') 中的路径字符串
        // componentPath =
        //   component.toString().match(/import\("(.*)"\)/)?.[1] || '';
        const match = component.toString().match(/import\("(.*)"\)/);
        if (match && match[1]) {
          // 替换 '/src' 为 '../views'
          // componentPath = match[1].replace('/src', '..');
          componentPath = meta?.componentPath
            ? meta.componentPath.replace('#/', '../')
            : match[1].replace('/src', '..');
          if (componentPath.includes('?t=')) {
            componentPath = componentPath.split('?')[0] || '';
          }
        }
      } catch {
        console.warn(`无法解析组件路径：${String(route.name)}`);
      }
    }

    const processedChildren = children
      ? backMenuToVbenMenu(children as RouteRecordRaw[], menuList)
      : undefined;

    const newRoute: RouteRecordStringComponent = {
      ...route,
      component: componentPath,
      children: processedChildren,
    };

    resultList.push(newRoute);
  }

  return resultList;
}

function hasPermission(menuSet: Set<string>, route: RouteRecordRaw) {
  return route.name ? menuSet.has(String(route.name)) : true;
}

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

  const layoutMap: ComponentRecordType = {
    BasicLayout,
    IFrameView,
    NotFoundComponent,
  };

  return await generateAccessible(preferences.app.accessMode, {
    ...options,
    fetchMenuListAsync: async () => {
      message.loading({
        content: '加载菜单中...',
        duration: 1.5,
      });
      // 后台返回路由/菜单
      const backMenuList = await getAllMenusApi();
      const menuList = backMenuToVbenMenu(
        options.routes,
        new Set(backMenuList),
      );
      return menuList;
    },
    // 可以指定没有权限跳转403页面
    forbiddenComponent,
    // 如果 route.meta.menuVisibleWithForbidden = true
    layoutMap,
    pageMap,
  });
}

export { generateAccess };
