import { useState, useEffect } from "react"; import { apiClient } from "@/lib/api/client"; // 전역 언어 상태 (다른 컴포넌트에서 접근 가능) let globalUserLang = "KR"; let globalChangeLangCallback: ((lang: string) => void) | null = null; export const useMultiLang = (options: { companyCode?: string } = {}) => { const [userLang, setUserLang] = useState("KR"); const companyCode = options.companyCode || "*"; // 전역 언어 상태 동기화 useEffect(() => { if (globalUserLang !== userLang) { setUserLang(globalUserLang); } }, [globalUserLang]); // 언어 변경 시 전역 콜백 호출 useEffect(() => { if (globalChangeLangCallback) { globalChangeLangCallback(userLang); } }, [userLang]); // 사용자 로케일 조회 (한 번만 실행) useEffect(() => { // 이미 로케일이 설정되어 있으면 중복 호출 방지 if (globalUserLang && globalUserLang !== "KR") { setUserLang(globalUserLang); return; } const fetchUserLocale = async () => { try { console.log("🔍 사용자 로케일 조회 시작"); const response = await apiClient.get("/admin/user-locale"); if (response.data.success && response.data.data) { const userLocale = response.data.data; console.log("✅ 사용자 로케일 조회 성공:", userLocale); // 데이터베이스의 locale 값을 그대로 사용 (매핑 없음) setUserLang(userLocale); globalUserLang = userLocale; // 전역 상태도 업데이트 return; } // API 호출 실패 시 브라우저 언어 사용 console.warn("⚠️ 사용자 로케일 조회 실패, 브라우저 언어 사용"); const browserLang = navigator.language.split("-")[0]; // 브라우저 언어를 그대로 사용 (매핑 없음) if (["ko", "en", "ja", "zh"].includes(browserLang)) { setUserLang(browserLang); globalUserLang = browserLang; } } catch (error) { console.error("❌ 사용자 로케일 조회 중 오류:", error); // 오류 시 브라우저 언어 사용 const browserLang = navigator.language.split("-")[0]; // 브라우저 언어를 그대로 사용 (매핑 없음) if (["ko", "en", "ja", "zh"].includes(browserLang)) { setUserLang(browserLang); globalUserLang = browserLang; } } }; fetchUserLocale(); }, []); // 다국어 텍스트 가져오기 (배치 조회 방식) const getText = async (menuCode: string, langKey: string, fallback?: string): Promise => { console.log(`🔍 다국어 텍스트 요청 (배치 방식):`, { menuCode, langKey, userLang, companyCode }); try { // 배치 조회 API 사용 const response = await apiClient.post( "/multilang/batch", { langKeys: [langKey], }, { params: { companyCode, menuCode, userLang, }, }, ); console.log(`📡 배치 API 응답 상태:`, response.status, response.statusText); if (response.data.success && response.data.data && response.data.data[langKey]) { // 번역 텍스트를 캐시에 저장 const cacheKey = `${menuCode}.${langKey}`; const currentCache = (window as any).__TRANSLATION_CACHE || {}; currentCache[cacheKey] = response.data.data[langKey]; (window as any).__TRANSLATION_CACHE = currentCache; return response.data.data[langKey]; } // 실패 시 fallback 또는 키 반환 console.log(`🔄 배치 API 성공했지만 데이터 없음, fallback 반환:`, fallback || langKey); return fallback || langKey; } catch (error) { console.error("❌ 다국어 텍스트 배치 조회 실패:", error); console.log(`🔄 에러 시 fallback 반환:`, fallback || langKey); return fallback || langKey; } }; // 언어 변경 const changeLang = async (newLang: string) => { try { // 백엔드에 사용자 로케일 설정 요청 const response = await apiClient.post("/admin/user-locale", { locale: newLang, }); if (response.data.success) { setUserLang(newLang); globalUserLang = newLang; console.log("✅ 사용자 로케일 변경 성공:", newLang); } else { console.error("❌ 사용자 로케일 변경 실패:", response.data.message); } } catch (error) { console.error("❌ 사용자 로케일 변경 중 오류:", error); // 오류 시에도 로컬 상태는 변경 setUserLang(newLang); globalUserLang = newLang; } }; // 전역 언어 상태 접근자 const getGlobalUserLang = () => globalUserLang; const setGlobalChangeLangCallback = (callback: (lang: string) => void) => { globalChangeLangCallback = callback; }; return { userLang, getText, changeLang, companyCode, getGlobalUserLang, setGlobalChangeLangCallback, }; };