/**
 * React Router framework 模式（SSG / 路径前缀多语言）专用的 i18n 配置。
 *
 * 与旧的 ./index.ts 的区别，以及为什么另起一份：
 *   - 旧配置面向纯 CSR 单页应用：用 LanguageDetector 从 querystring/navigator 探测语言，
 *     且初始语言包异步加载完成后（i18nReady.then）才挂载 React。这套「异步就绪再渲染」的模型
 *     与 SSG 的同步渲染冲突，且 Node 端没有 querystring/navigator。
 *   - 本配置面向 framework 模式：语言由路由 /:lang 段决定（见 routes），因此
 *       1) 初始语言固定为默认语言（en-US），资源同步内联，i18n.init 同步完成 → SSG 端可直接渲染；
 *       2) 不使用 LanguageDetector；
 *       3) hydrate 后由路由层调用 loadAndChangeLanguage() 切到 URL 指定的语言（其它语言懒加载）。
 *
 * 旧的 ./index.ts 保留不动，将来若再做纯 CSR 单页应用可继续复用。
 */
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import enUS from '@/locales/en-US';

import { DEFAULT_LANG, ENABLED_LANGS } from './langConfig';
import { getLangTarget } from './langMap';

/**
 * 非默认语言的懒加载入口。默认语言（en-US）已同步内联，不在此列。
 * import.meta.glob 不 eager，保证这些语言包按需加载、不进首屏包。
 */
const localeLoaders = import.meta.glob([
    '@/locales/*.ts',
    '!@/locales/dirMap.ts',
    '!@/locales/en-US.ts', // 默认语言已在上方静态内联，排除以避免「既静态又动态 import」告警
]);

const languageFiles: Record<string, () => Promise<unknown>> = {};
for (const [path, loader] of Object.entries(localeLoaders)) {
    const lang = path.split('/').pop()?.replace('.ts', '') || '';
    if (lang === DEFAULT_LANG) continue; // 默认语言已内联
    if (!ENABLED_LANGS.includes(lang as (typeof ENABLED_LANGS)[number])) continue;
    languageFiles[lang] = loader;
}

// 同步初始化：resources 里已内联默认语言，i18next 在此情形下 init 是同步完成的，
// 因此本模块被 import 后 i18n 立即可用于 SSG 端渲染，无需等待任何 Promise。
i18n.use(initReactI18next).init({
    lng: DEFAULT_LANG,
    fallbackLng: DEFAULT_LANG,
    supportedLngs: [...ENABLED_LANGS],
    resources: {
        [DEFAULT_LANG]: { translation: enUS },
    },
    interpolation: {
        escapeValue: false,
        prefix: '{',
        suffix: '}',
    },
    // 关闭异步初始化路径，确保同步就绪
    initImmediate: false,
});

/**
 * 加载指定语言的翻译包（若未加载）并切换到该语言。
 * 供路由层在客户端 hydrate 后，根据 URL 的 /:lang 段调用。
 * 仅在浏览器端执行按需加载；SSG 端不会走到这里。
 * @param rawLang URL 中的语言段（如 'en'、'zh'），内部经 getLangTarget 归一化为完整 locale。
 */
export async function loadAndChangeLanguage(rawLang: string): Promise<void> {
    const lang = getLangTarget(rawLang);

    if (!i18n.hasResourceBundle(lang, 'translation') && languageFiles[lang]) {
        try {
            const mod = (await languageFiles[lang]()) as { default: Record<string, unknown> };
            i18n.addResourceBundle(lang, 'translation', mod.default, true, true);
        } catch (error) {
            console.error(`i18n: failed to load language "${lang}"`, error);
            return;
        }
    }

    if (i18n.language !== lang) {
        await i18n.changeLanguage(lang);
    }
}

/** 把 URL 语言段归一化为受支持的 locale；不支持时回退默认语言。 */
export function resolveLang(rawLang: string | undefined): string {
    if (!rawLang) return DEFAULT_LANG;
    const target = getLangTarget(rawLang);
    return (ENABLED_LANGS as readonly string[]).includes(target) ? target : DEFAULT_LANG;
}

export default i18n;
