import { createContext, useContext, useState, useEffect, ReactNode } from "react"; import { LocalizedString } from "@/types/booth"; export type Language = "en" | "zh"; interface I18nContextType { language: Language; setLanguage: (lang: Language) => void; toggleLanguage: () => void; t: (field: LocalizedString | string | undefined, fallback?: string) => string; isWeChat: boolean; } const I18nContext = createContext(null); export function I18nProvider({ children }: { children: ReactNode }) { const [language, setLanguageState] = useState("zh"); const [isWeChat, setIsWeChat] = useState(false); useEffect(() => { if (typeof window !== "undefined") { // 1. Detect WeChat browser environment const ua = navigator.userAgent.toLowerCase(); const inWeChat = ua.includes("micromessenger"); setIsWeChat(inWeChat); // 2. Check stored preference first const stored = localStorage.getItem("booth_lang") as Language | null; if (stored === "en" || stored === "zh") { setLanguageState(stored); return; } // 3. Fallback to system / browser language const browserLang = (navigator.language || "").toLowerCase(); if (browserLang.startsWith("zh")) { setLanguageState("zh"); } else { setLanguageState("en"); } } }, []); const setLanguage = (lang: Language) => { setLanguageState(lang); if (typeof window !== "undefined") { localStorage.setItem("booth_lang", lang); } }; const toggleLanguage = () => { const nextLang = language === "zh" ? "en" : "zh"; setLanguage(nextLang); }; const t = (field: LocalizedString | string | undefined, fallback: string = ""): string => { if (!field) return fallback; if (typeof field === "string") return field; return field[language] || field.en || fallback; }; return ( {children} ); } export function useI18n() { const context = useContext(I18nContext); if (!context) { return { language: "zh" as Language, setLanguage: () => {}, toggleLanguage: () => {}, t: (field: LocalizedString | string | undefined, fallback: string = "") => { if (!field) return fallback; if (typeof field === "string") return field; return field.zh || field.en || fallback; }, isWeChat: false, }; } return context; }