"use strict";
// TypeScript i18next configuration with Fluent and manifest integration
// modified from https://github.com/inaturalist/iNaturalistReactNative/blob/main/src/i18n/initI18next.js
Object.defineProperty(exports, "__esModule", { value: true });
exports.i18next = exports.I18NEXT_CONFIG = void 0;
exports.getLocaleFromSystemLocale = getLocaleFromSystemLocale;
exports.getCurrentLocale = getCurrentLocale;
exports.getCurrentLocaleSync = getCurrentLocaleSync;
exports.default = initI18next;
exports.changeLanguage = changeLanguage;
exports.getCurrentLanguage = getCurrentLanguage;
exports.getSupportedLocales = getSupportedLocales;
exports.getLanguageInfo = getLanguageInfo;
exports.isLocaleSupported = isLocaleSupported;
const tslib_1 = require("tslib");
const i18next_1 = tslib_1.__importDefault(require("i18next"));
exports.i18next = i18next_1.default;
const i18next_fluent_1 = tslib_1.__importDefault(require("i18next-fluent"));
const i18next_resources_to_backend_1 = tslib_1.__importDefault(require("i18next-resources-to-backend"));
require("intl-pluralrules");
const react_i18next_1 = require("react-i18next");
// Import our manifest directly to avoid circular dependency
const manifest_json_1 = tslib_1.__importDefault(require("../../locales/manifest.json"));
const storage_1 = tslib_1.__importDefault(require("../storage"));
const LOCALE_STORAGE_KEY = "@streamplace/locale";
// Try to import expo-localization, but make it optional
let Localization = null;
try {
    const localizationModule = require("expo-localization");
    // Handle both default and named exports
    Localization = localizationModule.default
        ? localizationModule.default
        : localizationModule;
}
catch {
    // expo-localization not available, will use browser/fallback detection
}
function cleanLocaleName(locale) {
    return locale.replace("_", "-").replace(/@.*/, "");
}
function getLocaleFromSystemLocale() {
    let systemLocale = "en";
    // Try to get locale from expo-localization if available
    if (Localization && typeof Localization.getLocales === "function") {
        try {
            const locales = Localization.getLocales();
            systemLocale = locales?.[0]?.languageTag || "en";
        }
        catch (error) {
            console.warn("Failed to get locales from expo-localization:", error);
        }
    }
    else if (typeof navigator !== "undefined" && navigator.language) {
        // Fallback to browser navigator.language
        systemLocale = navigator.language;
    }
    const candidateLocale = cleanLocaleName(systemLocale);
    // Check if the full locale is supported (e.g., "en-US")
    if (manifest_json_1.default.supportedLocales.includes(candidateLocale)) {
        return candidateLocale;
    }
    // Check if the language part is supported (e.g., "en" from "en-GB")
    const lang = candidateLocale.split("-")[0];
    const matchingLocale = manifest_json_1.default.supportedLocales.find((locale) => locale.startsWith(lang + "-"));
    if (matchingLocale) {
        return matchingLocale;
    }
    // Fall back to default locale from manifest
    return manifest_json_1.default.fallbackChain[0];
}
// Cache for the current locale to avoid async lookups
let cachedLocale = null;
async function getCurrentLocale() {
    if (cachedLocale) {
        return cachedLocale;
    }
    const stored = await storage_1.default.getItem(LOCALE_STORAGE_KEY);
    if (stored && manifest_json_1.default.supportedLocales.includes(stored)) {
        cachedLocale = stored;
        return stored;
    }
    const systemLocale = getLocaleFromSystemLocale();
    cachedLocale = systemLocale;
    return systemLocale;
}
// Synchronous version for initial load - returns cached or system locale
function getCurrentLocaleSync() {
    return cachedLocale || getLocaleFromSystemLocale();
}
// Enhanced fallback logic using manifest
function getFallbackChain(code) {
    const fallbacks = [];
    if (!code)
        return manifest_json_1.default.fallbackChain;
    // Regional fallbacks
    if (code.match(/^es-/)) {
        fallbacks.push("es-ES"); // Spanish fallback
    }
    else if (code.match(/^fr-/)) {
        fallbacks.push("fr-FR"); // French fallback
    }
    else if (code.match(/^pt-/)) {
        fallbacks.push("pt-BR"); // Portuguese fallback
    }
    else if (code.match(/^zh-/)) {
        fallbacks.push("zh-Hant"); // Chinese fallback
    }
    // Add manifest fallback chain
    return [...fallbacks, ...manifest_json_1.default.fallbackChain];
}
// Use sync version for initial config - will be updated when storage loads
const LOCALE = getCurrentLocaleSync();
exports.I18NEXT_CONFIG = {
    lng: LOCALE,
    ns: ["common", "settings"], // Common should be first as it's most frequently used
    defaultNS: "common",
    interpolation: {
        escapeValue: false, // React already safes from XSS
    },
    react: {
        useSuspense: false, // Prevent Android crashes
    },
    i18nFormat: {
        fluentBundleOptions: {
            useIsolating: false,
            functions: {
                VOWORCON: ([txt]) => "aeiou".indexOf(txt[0].toLowerCase()) >= 0 ? "vow" : "con",
                JOIN: (args, opts = {}) => args
                    .filter(Boolean)
                    .filter((s) => typeof s === "string")
                    .join(opts.separator || ""),
            },
        },
    },
    load: "currentOnly",
    cleanCode: true,
    fallbackLng: getFallbackChain,
    supportedLngs: [...manifest_json_1.default.supportedLocales],
    debug: process.env.NODE_ENV === "development",
};
// Import platform-specific translation loader
// Metro will use i18n-loader.native.ts for React Native, i18n-loader.ts for web
const i18n_loader_1 = require("./i18n-loader");
// Translation loading function with error handling
async function loadTranslationData(locale, namespace) {
    try {
        const translations = await (0, i18n_loader_1.loadTranslationData)(locale, namespace);
        return translations;
    }
    catch (error) {
        console.error(`Failed to load ${namespace} translations for ${locale}:`, error);
        // Return minimal fallback
        return {
            loading: "Loading...",
            error: "Error",
            cancel: "Cancel",
        };
    }
}
// Initialize i18next with our configuration
let initPromise = null;
async function initI18next(config = {}) {
    // Return existing promise if already initializing
    if (initPromise) {
        return initPromise;
    }
    // Load stored locale from storage first
    const storedLocale = await getCurrentLocale();
    const finalConfig = {
        ...exports.I18NEXT_CONFIG,
        lng: storedLocale,
        ...config,
    };
    initPromise = i18next_1.default
        .use(react_i18next_1.initReactI18next)
        .use(i18next_fluent_1.default)
        .use((0, i18next_resources_to_backend_1.default)((locale, namespace, callback) => {
        // Load translations using our manifest-based namespace system
        loadTranslationData(locale, namespace)
            .then((translations) => callback(null, translations))
            .catch((error) => callback(error, null));
    }))
        .init(finalConfig)
        .then(() => {
        // Automatically persist language changes to storage
        i18next_1.default.on("languageChanged", (lng) => {
            if (lng && manifest_json_1.default.supportedLocales.includes(lng)) {
                cachedLocale = lng;
                storage_1.default.setItem(LOCALE_STORAGE_KEY, lng);
            }
        });
        return i18next_1.default;
    });
    return initPromise;
}
// Utility functions for language management
async function changeLanguage(locale) {
    // Storage is handled automatically via languageChanged event
    await i18next_1.default.changeLanguage(locale);
}
function getCurrentLanguage() {
    // Return the cached locale preference, not i18next's resolved language
    // i18next.language may return just "zh" instead of "zh-Hant"
    return getCurrentLocaleSync();
}
function getSupportedLocales() {
    return [...manifest_json_1.default.supportedLocales];
}
function getLanguageInfo(locale) {
    return manifest_json_1.default.languages[locale] || null;
}
function isLocaleSupported(locale) {
    return manifest_json_1.default.supportedLocales.includes(locale);
}
// Auto-initialize i18next on module load
// This ensures the instance is ready when used in providers
initI18next().catch((error) => {
    console.error("Failed to auto-initialize i18n:", error);
});
//# sourceMappingURL=i18next-config.js.map