import { createContext, useContext, useEffect, useMemo, useState } from 'react' import en from './locales/en.json' import zh from './locales/zh.json' const STORAGE_KEY = 'ds2api_lang' const translations = { en, zh } const I18nContext = createContext({ lang: 'zh', setLang: () => {}, t: (key) => key, }) const getBrowserLang = () => { if (typeof navigator === 'undefined') return 'zh' return navigator.language?.toLowerCase().startsWith('zh') ? 'zh' : 'en' } const getValue = (obj, key) => { if (!obj) return undefined return key.split('.').reduce((acc, part) => (acc ? acc[part] : undefined), obj) } const formatMessage = (message, vars) => { if (!vars) return message return message.replace(/\{(\w+)\}/g, (match, key) => { if (Object.prototype.hasOwnProperty.call(vars, key)) { return vars[key] } return match }) } export const I18nProvider = ({ children }) => { const [lang, setLang] = useState(() => { if (typeof localStorage === 'undefined') return getBrowserLang() return localStorage.getItem(STORAGE_KEY) || getBrowserLang() }) useEffect(() => { if (typeof localStorage !== 'undefined') { localStorage.setItem(STORAGE_KEY, lang) } if (typeof document !== 'undefined') { document.documentElement.lang = lang === 'zh' ? 'zh-CN' : 'en' } }, [lang]) const t = useMemo(() => { return (key, vars) => { const value = getValue(translations[lang], key) ?? getValue(translations.en, key) ?? key if (typeof value !== 'string') return value return formatMessage(value, vars) } }, [lang]) const contextValue = useMemo(() => ({ lang, setLang, t }), [lang, t]) return {children} } export const useI18n = () => useContext(I18nContext)