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

import { generateAccessible } from '@vben/access';
import { $te } from '@vben/locales';
import { preferences } from '@vben/preferences';
import { useAccessStore } from '@vben/stores';
import { convertServerMenuToRouteRecordStringComponent } from '@vben/utils';

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

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

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

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

  return await generateAccessible(preferences.app.accessMode, {
    ...options,
    fetchMenuListAsync: async () => {
      // 由于 yudao 通过 accessStore 读取，所以不在进行 message.loading 提示
      // 补充说明：accessStore.accessMenus 一开始是 AppRouteRecordRaw 类型（后端加载），后面被赋值成 MenuRecordRaw 类型（前端转换）
      const accessMenus = accessStore.accessMenus as AppRouteRecordRaw[];

      return convertServerMenuToRouteRecordStringComponent(
        convertMenuToI18nKey(accessMenus),
      );
    },
    // 可以指定没有权限跳转403页面
    forbiddenComponent,
    // 如果 route.meta.menuVisibleWithForbidden = true
    layoutMap,
    pageMap,
  });
}

/**
 * 将菜单名称转换为国际化键
 * @param menuList 菜单列表
 * @returns 转换后的菜单列表
 */
function convertMenuToI18nKey(
  menuList: AppRouteRecordRaw[],
): AppRouteRecordRaw[] {
  return menuList.map((menu) => {
    const { i18nKey } = menu;
    if (i18nKey) {
      menu.name = $te(i18nKey) ? i18nKey : menu.name;
    }
    if (menu.children) {
      menu.children = convertMenuToI18nKey(menu.children);
    }
    return menu;
  });
}

export { generateAccess };
