import type {
  ComponentRecordType,
  GenerateMenuAndRoutesOptions,
  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';
import { $t } from '#/locales';

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

const PRODUCT_PATH = '/product';
const PRODUCT_DETAIL_PATH = '/product/detail';
const PRODUCT_DETAIL_NAME = 'ProductDetail';
const PRODUCT_LIST_PATH = '/product/list';

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

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

  return await generateAccessible(preferences.app.accessMode, {
    ...options,
    fetchMenuListAsync: async () => {
      message.loading({
        content: `${$t('common.loadingMenu')}...`,
        duration: 1.5,
      });
      const menuList = await getAllMenusApi();
      return ensureProductDetailRoute(menuList);
    },
    // 可以指定没有权限跳转403页面
    forbiddenComponent,
    // 如果 route.meta.menuVisibleWithForbidden = true
    layoutMap,
    pageMap,
  });
}

function ensureProductDetailRoute(
  routes: RouteRecordStringComponent[],
): RouteRecordStringComponent[] {
  const clonedRoutes = cloneMenuRoutes(routes);
  if (containsRoute(clonedRoutes, PRODUCT_DETAIL_PATH, PRODUCT_DETAIL_NAME)) {
    return clonedRoutes;
  }

  const productRoute = findProductRoute(clonedRoutes);
  if (!productRoute) {
    return clonedRoutes;
  }

  const productChildren = [...(productRoute.children ?? [])];
  const listMeta = productChildren.find(
    (item) => String(item.path || '').trim() === PRODUCT_LIST_PATH,
  )?.meta;

  productChildren.push({
    name: PRODUCT_DETAIL_NAME,
    path: PRODUCT_DETAIL_PATH,
    component: '/views/product/detail/index.vue',
    meta: {
      ...listMeta,
      title: '商品详情',
      hideInMenu: true,
    },
  });

  productRoute.children = productChildren;
  return clonedRoutes;
}

function cloneMenuRoutes(
  routes: RouteRecordStringComponent[],
): RouteRecordStringComponent[] {
  return routes.map((route) => ({
    ...route,
    meta: route.meta ? { ...route.meta } : route.meta,
    children: route.children ? cloneMenuRoutes(route.children) : undefined,
  }));
}

function containsRoute(
  routes: RouteRecordStringComponent[],
  path: string,
  name: string,
): boolean {
  for (const route of routes) {
    const routePath = String(route.path || '').trim();
    const routeName = String(route.name || '').trim();
    if (routePath === path || routeName === name) {
      return true;
    }
    if (route.children && containsRoute(route.children, path, name)) {
      return true;
    }
  }
  return false;
}

function findProductRoute(
  routes: RouteRecordStringComponent[],
): null | RouteRecordStringComponent {
  for (const route of routes) {
    const routePath = String(route.path || '').trim();
    const routeName = String(route.name || '').trim();
    const hasProductListChild = (route.children ?? []).some(
      (item) => String(item.path || '').trim() === PRODUCT_LIST_PATH,
    );

    if (
      routePath === PRODUCT_PATH ||
      routeName === 'Product' ||
      hasProductListChild
    ) {
      return route;
    }

    if (route.children) {
      const nestedMatch = findProductRoute(route.children);
      if (nestedMatch) {
        return nestedMatch;
      }
    }
  }
  return null;
}

export { generateAccess };
