import i18next from 'i18next';
import { matchPath } from 'react-router-dom';

import routerConfig from './routes';

import type { AppRouteObject } from './types';

/**
 * 扁平化路由配置，提取所有有 name 的路由
 */
function getAllRoutes(
    routes: AppRouteObject[],
    parentNames: string[] = []
): Array<{
    path: string;
    locale: string;
}> {
    const result: Array<{ path: string; locale: string }> = [];

    for (const route of routes) {
        if (route.name && route.path && !route.index) {
            const locale = route.locale || `menus.${[...parentNames, route.name].join('.')}`;
            result.push({ path: route.path, locale });
        }

        if (route.children) {
            const currentNames = route.name ? [...parentNames, route.name] : parentNames;
            result.push(...getAllRoutes(route.children, currentNames));
        }
    }

    return result;
}

let allRoutesCache: Array<{ path: string; locale: string }> | null = null;
function getAllRoutesCache(): Array<{ path: string; locale: string }> {
    if (!allRoutesCache) {
        allRoutesCache = getAllRoutes(routerConfig);
    }
    return allRoutesCache;
}

/**
 * 根据路径获取 locale key
 * @param pathname 路由路径
 * @returns locale key
 */
export const getLocaleByPath = (pathname: string): string => {
    const allRoutes = getAllRoutesCache();
    // 按路径长度降序排序，优先匹配更具体的路由
    const matchedRoute = allRoutes
        .filter((route) => {
            if (route.path === '*') return true;
            return matchPath({ path: route.path, end: false }, pathname) !== null;
        })
        .sort((a, b) => {
            if (a.path === '*') return 1;
            if (b.path === '*') return -1;
            return b.path.length - a.path.length;
        })[0];

    if (matchedRoute) {
        return matchedRoute.locale;
    }

    // 如果找不到对应的路由，将路径转换为 i18n key
    return `menus.${pathname.slice(1).replace(/\//g, '.')}`;
};

/**
 * 获取路由路径对应的标题
 * @param pathname 路由路径
 * @returns 路由标题
 */
export const getTitleByPath = (pathname: string): string => {
    const locale = getLocaleByPath(pathname);
    return i18next.t(locale, { defaultValue: '' });
};
