'use client' import { createContext, useContext, useEffect, useState, useCallback, useRef } from 'react' import type { ReactNode } from 'react' import { SupportedLanguage, loadTranslations, getTranslationValue, Translations } from './load-translations' type LanguageContextType = { language: SupportedLanguage setLanguage: (lang: SupportedLanguage) => void t: (key: string, params?: Record) => string translations: Translations } const LanguageContext = createContext(undefined) const RTL_LANGUAGES: SupportedLanguage[] = ['ar', 'fa'] function updateDocumentDirection(lang: SupportedLanguage) { document.documentElement.lang = lang document.documentElement.dir = RTL_LANGUAGES.includes(lang) ? 'rtl' : 'ltr' } export function LanguageProvider({ children, initialLanguage = 'en' }: { children: ReactNode initialLanguage?: SupportedLanguage }) { const [language, setLanguageState] = useState(initialLanguage) const [translations, setTranslations] = useState(null) const cacheRef = useRef>(new Map()) // Load translations when language changes (with caching) useEffect(() => { const cached = cacheRef.current.get(language) if (cached) { setTranslations(cached) updateDocumentDirection(language) return } const loadLang = async () => { const loaded = await loadTranslations(language) cacheRef.current.set(language, loaded) setTranslations(loaded) updateDocumentDirection(language) } loadLang() }, [language]) // Load saved language from localStorage on mount useEffect(() => { const saved = localStorage.getItem('user-language') as SupportedLanguage if (saved) { setLanguageState(saved) } else { // Auto-detect from browser language const browserLang = navigator.language.split('-')[0] as SupportedLanguage const supportedLangs: SupportedLanguage[] = ['en', 'fr', 'es', 'de', 'fa', 'it', 'pt', 'ru', 'zh', 'ja', 'ko', 'ar', 'hi', 'nl', 'pl'] if (supportedLangs.includes(browserLang)) { setLanguageState(browserLang) localStorage.setItem('user-language', browserLang) } } }, []) const setLanguage = useCallback((lang: SupportedLanguage) => { setLanguageState(lang) localStorage.setItem('user-language', lang) updateDocumentDirection(lang) }, []) const t = useCallback((key: string, params?: Record) => { if (!translations) return key let value: any = getTranslationValue(translations, key) // Replace parameters like {count}, {percentage}, etc. if (params && typeof value === 'string') { Object.entries(params).forEach(([param, paramValue]) => { value = value.replace(`{${param}}`, String(paramValue)) }) } return typeof value === 'string' ? value : key }, [translations]) // During initial load, show children with the initial language as fallback // to prevent blank flash if (!translations) { return ( key, translations: {} as Translations }}> {children} ) } return ( {children} ) } export function useLanguage() { const context = useContext(LanguageContext) if (context === undefined) { throw new Error('useLanguage must be used within a LanguageProvider') } return context }