import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"; import { DEFAULT_EXTERNAL_LOCALE, EXTERNAL_LANGUAGE_OPTIONS, EXTERNAL_LOCALE_STORAGE_KEY, externalDirection, externalMessage, normalizeExternalLocale } from "./messages.js"; const defaultTranslate = (key, values) => interpolate(externalMessage(DEFAULT_EXTERNAL_LOCALE, key), values); const ExternalI18nContext = createContext({ direction: "ltr", languages: EXTERNAL_LANGUAGE_OPTIONS, locale: DEFAULT_EXTERNAL_LOCALE, setLocale: () => {}, t: defaultTranslate }); export function ExternalI18nProvider({ children }) { // The product default is deliberately English. Browser language is ignored until the operator explicitly chooses and persists another locale. const [locale, setLocaleState] = useState(readPersistedLocale); const direction = externalDirection(locale); const setLocale = useCallback((nextLocale) => { const normalized = normalizeExternalLocale(nextLocale); setLocaleState(normalized); try { globalThis.localStorage?.setItem(EXTERNAL_LOCALE_STORAGE_KEY, normalized); } catch { // Storage can be unavailable in hardened/private browser contexts; the in-memory locale still changes for the current session. } }, []); const t = useCallback((key, values) => interpolate(externalMessage(locale, key), values), [locale]); useEffect(() => { // Keep native controls, assistive technology, MUI portals and the shell aligned when Arabic changes writing direction. const root = globalThis.document?.documentElement; if (!root) { return; } root.lang = locale; root.dir = direction; globalThis.document.body?.setAttribute("dir", direction); }, [direction, locale, t]); const value = useMemo( () => ({ direction, languages: EXTERNAL_LANGUAGE_OPTIONS, locale, setLocale, t }), [direction, locale, setLocale, t] ); return {children}; } export function useExternalI18n() { return useContext(ExternalI18nContext); } function readPersistedLocale() { try { return normalizeExternalLocale(globalThis.localStorage?.getItem(EXTERNAL_LOCALE_STORAGE_KEY)); } catch { return DEFAULT_EXTERNAL_LOCALE; } } function interpolate(message, values = {}) { return String(message).replace(/\{(\w+)\}/g, (match, key) => (values[key] === undefined ? match : String(values[key]))); }