import { useState, useEffect, useCallback } from 'react'; import { translationsApi } from './api'; import { useLanguageStore, translateCarName, Language } from './i18n'; // Cache for translations to avoid repeated API calls const translationCache: Record> = {}; export function useTranslate() { const { language } = useLanguageStore(); const [translations, setTranslations] = useState>({}); const [loading, setLoading] = useState(false); // Get cache key for current language const cacheKey = `trans_${language}`; // Load translations from cache on mount useEffect(() => { if (translationCache[cacheKey]) { setTranslations(translationCache[cacheKey]); } }, [cacheKey]); // Translate a single text const translate = useCallback((text: string | undefined | null): string => { if (!text) return ''; if (language === 'ko') return text; // Korean is source, no translation needed // Try static translations FIRST (for fuel, transmission, car names, etc.) const staticTranslation = translateCarName(text, language as Language); if (staticTranslation !== text) { return staticTranslation; } // Then check API cache for other translations const cached = translationCache[cacheKey]?.[text]; if (cached) return cached; return text; // Fallback to original if no translation found }, [language, cacheKey]); // Bulk load translations for multiple texts const loadTranslations = useCallback(async (texts: string[], category?: string) => { if (language === 'ko') return; // No need to translate Korean // Filter out already cached texts const uncachedTexts = texts.filter( t => t && !translationCache[cacheKey]?.[t] ); if (uncachedTexts.length === 0) return; setLoading(true); try { // Map language code to API expected format const langCode = language === 'mn' ? 'mn' : language === 'ru' ? 'ru' : 'en'; const result = await translationsApi.bulkLookup(uncachedTexts, langCode, category); // Update cache if (!translationCache[cacheKey]) { translationCache[cacheKey] = {}; } Object.assign(translationCache[cacheKey], result.translations); setTranslations({ ...translationCache[cacheKey] }); } catch (err) { console.error('Failed to load translations:', err); } finally { setLoading(false); } }, [language, cacheKey]); // Translate car object fields const translateCar = useCallback((car: { car_name?: string; fuel?: string; transmission?: string; color?: string; maker?: { name: string }; model?: { name: string }; }) => { return { car_name: translate(car.car_name), fuel: translate(car.fuel), transmission: translate(car.transmission), color: translate(car.color), maker_name: translate(car.maker?.name), model_name: translate(car.model?.name), }; }, [translate]); // Preload translations for a list of cars const preloadCarTranslations = useCallback(async (cars: Array<{ car_name?: string; fuel?: string; transmission?: string; color?: string; maker?: { name: string }; model?: { name: string }; }>) => { const textsToTranslate: string[] = []; cars.forEach(car => { if (car.car_name) textsToTranslate.push(car.car_name); if (car.fuel) textsToTranslate.push(car.fuel); if (car.transmission) textsToTranslate.push(car.transmission); if (car.color) textsToTranslate.push(car.color); if (car.maker?.name) textsToTranslate.push(car.maker.name); if (car.model?.name) textsToTranslate.push(car.model.name); }); // Remove duplicates const uniqueTexts = Array.from(new Set(textsToTranslate)); if (uniqueTexts.length > 0) { await loadTranslations(uniqueTexts); } }, [loadTranslations]); return { translate, translateCar, loadTranslations, preloadCarTranslations, loading, }; } // Clear translation cache (useful when translations are updated) export function clearTranslationCache() { Object.keys(translationCache).forEach(key => { delete translationCache[key]; }); }