import type { AgentConfig } from './api';

/**
 * Module-singleton copy map. Populated once on /init from
 * `agent.copy`. Reads everywhere else are zero-cost dictionary
 * lookups — no React context, no prop drilling, no per-render
 * subscription overhead. Keeps the widget bundle thin.
 */
let copy: Record<string, string> = {};
let locale = 'en';
let rtl = false;

// Locales the agent might pin via `agent.language_default`. Mirrors
// (a subset of) LocaleCatalog::RTL_LOCALES on the server. Kept as a
// hard-coded list so the widget bundle stays thin — the server still
// auto-discovers the full RTL set via the catalog, this is just the
// glyphs we need at render time.
const RTL_LOCALES = new Set([
    'ar',
    'arc',
    'dv',
    'fa',
    'he',
    'ku',
    'ps',
    'sd',
    'ug',
    'ur',
    'yi',
]);

export function setI18n(agent: AgentConfig | null): void {
    copy = agent?.copy ?? {};
    locale = agent?.locale ?? 'en';
    rtl = RTL_LOCALES.has(locale.toLowerCase());
}

/**
 * True when the active locale is right-to-left. Drives the shadow-root
 * `dir` attribute and the .flip-rtl utility on directional icons.
 */
export function isRtl(): boolean {
    return rtl;
}

/**
 * Translate an English source string. Missing keys fall back to the
 * source so a fresh deploy on a new locale never shows blanks.
 *
 * Both `:placeholder` and `{placeholder}` markers are interpolated.
 */
export function t(
    key: string,
    replacements?: Record<string, string | number>,
): string {
    let line = copy[key] ?? key;

    if (replacements) {
        for (const k in replacements) {
            const value = String(replacements[k]);
            line = line
                .replace(new RegExp(':' + k + '\\b', 'g'), value)
                .replace(new RegExp('\\{' + k + '\\}', 'g'), value);
        }
    }

    return line;
}

export function widgetLocale(): string {
    return locale;
}
