"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports._detectDocumentLanguage = _detectDocumentLanguage;
exports.addTranslations = addTranslations;
exports.fallbackLocale = fallbackLocale;
exports.getLanguage = getLanguage;
exports.getTranslations = getTranslations;
exports.languageMatches = languageMatches;
exports.setLanguage = setLanguage;
exports.t = t;
exports.tWithLanguage = tWithLanguage;
exports.translate = translate;
var _en = _interopRequireDefault(require("./locale/en.json"));
var _es = _interopRequireDefault(require("./locale/es.json"));
var _get = _interopRequireDefault(require("lodash/get"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _detectDocumentLanguage() {
  if (typeof document === 'undefined') {
    return undefined;
  }
  const detectedLang = document.querySelector('html')?.lang ?? '';
  const validLangs = ['en', 'es'];
  for (const lang of validLangs) {
    if (languageMatches(lang, detectedLang)) {
      return lang;
    }
  }
  return undefined;
}
let language = _detectDocumentLanguage() ?? 'en';
function getLanguage() {
  return language;
}
function setLanguage(lang) {
  language = lang;
}
function getTranslations() {
  let lang = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLanguage();
  return languageMatches('en', lang) ? _en.default : _es.default;
}
function addTranslations(lang, translations) {
  Object.assign(getTranslations(lang), translations);
}

/**
 * Because language strings can contain region subtags, we need a way to compare
 * just the language portion of two language strings. This function compares two
 * locale strings that may or may not contain subtags according to IETF BCP 47.
 * The second string defaults to our globally set language.
 */
function languageMatches(localeStringA) {
  let localeStringB = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getLanguage();
  const langA = localeStringA.split('-')[0];
  const langB = localeStringB.split('-')[0];
  return langA === langB;
}

/**
 * Falls back to a more generic locale if the more specific one isn't
 * available in this browser. Testing platforms tend to have only a
 * few locales.
 */
function fallbackLocale(language, subtag) {
  try {
    const locale = `${language}-${subtag}`;
    // If the locale string is invalid, the following line will fail and jump to
    // our catch block; otherwise, it is valid and safe to return it.
    new Date().toLocaleString(locale);
    return locale;
  } catch (error) {
    return language;
  }
}

/**
 * Returns the translation for a given key for a given language. For most
 * use cases, the `t` function will be more appropriate, where the language
 * is not a required parameter. Use this when you need a translation from
 * a specific language.
 */
function translate() {
  let lang = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getLanguage();
  let key = arguments.length > 1 ? arguments[1] : undefined;
  let data = arguments.length > 2 ? arguments[2] : undefined;
  const rawTranslation = (0, _get.default)(getTranslations(lang), key);
  if (typeof rawTranslation !== 'string') {
    throw new Error(`Translation key '${key}' does not resolve to a string.`);
  }
  if (data) {
    // Replace template strings with provided data
    const interpolatedTranslation = Object.keys(data).reduce((interpolatedString, dataKey) => interpolatedString.replace(`{{${dataKey}}}`, data[dataKey]), rawTranslation);
    return interpolatedTranslation;
  } else {
    return rawTranslation;
  }
}

/**
 * Returns the translation for a given key in the currently set language.
 */
function t(key, data) {
  return translate(getLanguage(), key, data);
}
/**
 * Returns a translation function bound to a specific language.
 *
 * Note that we don't want to use this to create the default `t` function
 * because it will bind with whatever the default language is AT THAT TIME,
 * so if the global language changes after we call this function,
 * translations coming out if it wouldn't pick up on the change.
 */
function tWithLanguage(lang) {
  return function t(key, data) {
    return translate(lang, key, data);
  };
}