/**
 * Maps 2-letter ISO 639-1 codes (`en`, `ru`, `ko` — what
 * `@djangocfg/i18n` exposes via `useLocale()`) to BCP-47 tags
 * (`en-US`, `ru-RU`, `ko-KR`) that the Web Speech API and most cloud
 * STT services expect.
 *
 * We keep a small built-in table for the locales we ship translations
 * for; codes outside it are looked up in the full Web Speech catalogue
 * (so `uk` → `uk-UA`, not the invalid `uk-UK`), and only fall through
 * to `<code>-<UPPER(code)>` as a last resort. The mapping is also
 * re-exported so consumers can extend it.
 */

import { WEB_SPEECH_LANGUAGES } from './languages-catalog';

const ISO_TO_BCP47: Record<string, string> = {
  en: 'en-US',
  ru: 'ru-RU',
  ko: 'ko-KR',
  ja: 'ja-JP',
  zh: 'zh-CN',
  de: 'de-DE',
  fr: 'fr-FR',
  it: 'it-IT',
  es: 'es-ES',
  nl: 'nl-NL',
  ar: 'ar-SA',
  tr: 'tr-TR',
  pl: 'pl-PL',
  sv: 'sv-SE',
  no: 'nb-NO',
  da: 'da-DK',
  pt: 'pt-BR',
};

export const DEFAULT_ISO_TO_BCP47 = ISO_TO_BCP47;

/** ISO-639 primary subtag → default catalogue dialect (e.g. `uk` → `uk-UA`). */
const CATALOG_ISO_TO_TAG: Record<string, string> = (() => {
  const map: Record<string, string> = {};
  for (const lang of WEB_SPEECH_LANGUAGES) {
    const first = lang.dialects[0];
    if (first) map[lang.iso.toLowerCase()] = first.code;
  }
  return map;
})();

/**
 * Normalise any of:
 *   - BCP-47 ("en-US", "ru-RU") — passed through.
 *   - ISO 639-1 ("en", "ru")    — mapped via the built-in table, then
 *                                 the full Web Speech catalogue, then
 *                                 `<code>-<UPPER(code)>` as a last
 *                                 resort.
 *   - `null`/`undefined`/empty  — returns `undefined`.
 */
export function toBCP47(
  code: string | null | undefined,
  table: Record<string, string> = ISO_TO_BCP47,
): string | undefined {
  if (!code) return undefined;
  const trimmed = code.trim();
  if (!trimmed) return undefined;
  if (trimmed.includes('-')) return trimmed; // already BCP-47
  const lower = trimmed.toLowerCase();
  return (
    table[lower] ?? CATALOG_ISO_TO_TAG[lower] ?? `${lower}-${lower.toUpperCase()}`
  );
}

/**
 * Resolve the language tag for a speech session in priority order:
 *   1. `explicit` prop (always wins) — host-supplied override.
 *   2. `prefs`    — value stored in `useSpeechPrefs` (user picked it
 *                   via `<LanguagePicker>` or programmatically).
 *   3. `i18n`     — current i18n locale (2-letter ISO).
 *   4. `navigator.language` — browser default.
 *   5. `'en-US'`  — last-resort safety net.
 *
 * All inputs may be ISO-2 or BCP-47; the function normalises before
 * returning.
 */
export function resolveSpeechLanguage(opts: {
  explicit?: string;
  prefs?: string | null;
  i18n?: string | null;
}): string {
  return (
    toBCP47(opts.explicit) ??
    toBCP47(opts.prefs) ??
    toBCP47(opts.i18n) ??
    toBCP47(typeof navigator !== 'undefined' ? navigator.language : null) ??
    'en-US'
  );
}
