/**
 * Req-F-036 i18n framework — Phase 1 baseline.
 *
 * Sprint 1 scope: load JSON dictionaries from ./locales/<code>.json, expose
 * t(key, locale) + dictFor(locale) so the rest of the codebase can call
 * through to localized strings. Sprint 4 (F-036) extends coverage to every
 * user-facing string and adds runtime locale switching in BDash.
 *
 * Languages day-1: CS (Czech, primary — sametic.cz pilot), SK, EN, UK
 * (Ukrainian; CO confirmed Ukrainian recipients are common for COD-to-UA).
 *
 * Locale resolution:
 *   - BC: an explicit language override (top-bar picker) wins everywhere. On
 *     "Auto" the main window follows the OS/env locale and the injected overlay
 *     follows the Shoptet admin <html lang="cs|sk|en|...">; any language we
 *     don't ship falls back to EN via autoDetect() (normalize() → CS is kept
 *     only as dictFor's structural safety net).
 *   - BDash: from a user setting (Sprint 4 — TBD UI).
 *   - Backend errors: from Accept-Language header (Sprint 4); CS default.
 *
 * UMD: works in Node (require('shared/i18n')) and the browser (loaded as
 * inline script + globalThis.NP.i18n). The browser path is unused in
 * Sprint 1 — BC injects a pre-resolved dict via config.translations on the
 * orders-list install script (see electron-app/main/shoptet-bridge.js).
 */

(function (root) {
  // SUPPORTED — order is preference order: CS first because it's the pilot
  // shop's locale; EN last because it's the universal fallback.
  var SUPPORTED = ['cs', 'sk', 'en', 'uk'];
  var DEFAULT_LOCALE = 'cs';
  var FALLBACK_LOCALE = 'en';

  // In Node, lazy-load JSON dicts via require so the bundler can statically
  // see them. In the browser, dicts are pre-injected as root.NP.i18nDicts
  // (the install script bundles the resolved one).
  var dicts = {};
  if (typeof require === 'function' && typeof module !== 'undefined') {
    SUPPORTED.forEach(function (code) {
      try {
        dicts[code] = require('./locales/' + code + '.json');
      } catch (e) {
        // Locale file missing — log once at startup. Translator falls back.
        if (typeof console !== 'undefined') {
          console.warn('[i18n] missing locale file: ' + code + '.json');
        }
        dicts[code] = {};
      }
    });
  } else if (root && root.NP && root.NP.i18nDicts) {
    dicts = root.NP.i18nDicts;
  }

  // Map a locale code or BCP-47 tag to a SUPPORTED code, or `fallback` when the
  // input is empty or a language we don't ship. Inputs we expect in the wild:
  //   "cs", "cs-CZ", "CS"  → "cs"
  //   "ua"                 → "uk"  (country code → language code)
  //   "en-US", "en-GB"     → "en"
  function resolveTo(input, fallback) {
    if (!input) return fallback;
    var primary = String(input).toLowerCase().replace(/_/g, '-').split('-')[0];
    // The "UA" alias — spec says 4-language CS/SK/EN/UA but Ukrainian's ISO
    // 639-1 code is `uk`. We accept both at the API boundary so callers don't
    // have to remember the distinction.
    if (primary === 'ua') primary = 'uk';
    if (SUPPORTED.indexOf(primary) !== -1) return primary;
    return fallback;
  }

  // normalize() — the historical default: unknown/empty falls to the CS pilot
  // default. Kept for dictFor's structural safety net and API back-compat.
  function normalize(input) { return resolveTo(input, DEFAULT_LOCALE); }

  // autoDetect() — used when BC is on "Auto" (no explicit language override):
  // the overlay follows the Shoptet admin <html lang> and the main window
  // follows the OS/env locale, but any language we don't ship lands on English
  // (the universal fallback), NOT Czech.
  function autoDetect(input) { return resolveTo(input, FALLBACK_LOCALE); }

  function dictFor(locale) {
    return dicts[normalize(locale)] || dicts[DEFAULT_LOCALE] || {};
  }

  // Look up a key with a 3-tier fallback:
  //   1. requested locale's dict
  //   2. EN dict (universal fallback)
  //   3. the key itself (visible breakage signal in dev)
  function t(key, locale) {
    var L = normalize(locale);
    var d = dicts[L];
    if (d && Object.prototype.hasOwnProperty.call(d, key)) return d[key];
    if (L !== FALLBACK_LOCALE && dicts[FALLBACK_LOCALE]
        && Object.prototype.hasOwnProperty.call(dicts[FALLBACK_LOCALE], key)) {
      return dicts[FALLBACK_LOCALE][key];
    }
    return key;
  }

  // Browser-only: build a minimal translator over a single resolved dict.
  // Used by injected scripts (orders-list) where loading the full registry
  // would balloon the inject payload.
  function buildTranslator(dict) {
    return function (key) {
      if (dict && Object.prototype.hasOwnProperty.call(dict, key)) return dict[key];
      return key;
    };
  }

  var api = {
    t: t,
    dictFor: dictFor,
    buildTranslator: buildTranslator,
    normalize: normalize,
    autoDetect: autoDetect,
    SUPPORTED: SUPPORTED,
    DEFAULT_LOCALE: DEFAULT_LOCALE,
    FALLBACK_LOCALE: FALLBACK_LOCALE
  };

  if (typeof module !== 'undefined' && module.exports) module.exports = api;
  else { root.NP = root.NP || {}; root.NP.i18n = api; }
})(typeof self !== 'undefined' ? self : this);
