import i18n from 'i18next';
import Backend from 'i18next-locize-backend';
import LastUsed from 'locize-lastused';
import Editor from 'locize-editor';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
import customDebug from './debugger';
import pkg from '../package.json';
import { debugMode, detectionOptions } from './config';

// Note: The index.js files inside src/locales are dynamically generated
// by the pullTranslations.sh script
import locales from './locales';

function addLocales(newLocales) {
  customDebug(`Adding locales ${newLocales}`, 'info');

  let resourceBundle = [];

  Object.keys(newLocales).map(key => {
    Object.keys(newLocales[key]).map(namespace => {
      const locale = newLocales[key][namespace];
      resourceBundle.push({ key, namespace, locale });
      i18n.addResourceBundle(key, namespace, locale, true, true);
    });
  });

  customDebug(`Locales added successfully`, 'info');
  customDebug(resourceBundle, 'info');
}

// Note: Developers can add the API key to use the in-context editor.
// DO NOT commit the API key
const config = (window.config && window.config.i18n) || {};

const locizeOptions = {
  projectId: config.LOCIZE_PROJECTID,
  apiKey: config.LOCIZE_API_KEY,
  referenceLng: 'en-US',
  fallbacklng: 'en-US',
};

const envUseLocize = !!config.USE_LOCIZE;
const envApiKeyAvailable = !!config.LOCIZE_API_KEY;

function initI18n(
  detection = detectionOptions,
  useLocize = envUseLocize,
  apiKeyAvailable = envApiKeyAvailable
) {
  let initialized;

  if (useLocize) {
    customDebug(`Using Locize for translation files`, 'info');
    initialized = i18n
      // i18next-locize-backend
      // loads translations from your project, saves new keys to it (saveMissing: true)
      // https://github.com/locize/i18next-locize-backend
      .use(Backend)
      // locize-lastused
      // sets a timestamp of last access on every translation segment on locize
      // -> safely remove the ones not being touched for weeks/months
      // https://github.com/locize/locize-lastused
      .use(LastUsed)
      // locize-editor
      // InContext Editor of locize ?locize=true to show it
      // https://github.com/locize/locize-editor
      .use(Editor)
      // detect user language
      // learn more: https://github.com/i18next/i18next-browser-languageDetector
      .use(LanguageDetector)
      // pass the i18n instance to react-i18next.
      .use(initReactI18next)
      // init i18next
      // for all options read: https://www.i18next.com/overview/configuration-options
      .init({
        fallbackLng: 'en-US',
        saveMissing: apiKeyAvailable,
        debug: debugMode,
        keySeparator: false,
        interpolation: {
          escapeValue: false, // not needed for react as it escapes by default
        },
        detection,
        backend: locizeOptions,
        locizeLastUsed: locizeOptions,
        editor: {
          ...locizeOptions,
          onEditorSaved: async (lng, ns) => {
            // reload that namespace in given language
            await i18n.reloadResources(lng, ns);
            // trigger an event on i18n which triggers a rerender
            // based on bindI18n below in react options
            i18n.emit('editorSaved');
          },
        },
        react: {
          useSuspense: false, // TODO: Was seeing weird errors without this
          wait: true,
          bindI18n: 'languageChanged editorSaved',
        },
      });
  } else {
    customDebug(`Using local translation files`, 'info');
    initialized = i18n
      // detect user language
      // learn more: https://github.com/i18next/i18next-browser-languageDetector
      .use(LanguageDetector)
      // pass the i18n instance to react-i18next.
      .use(initReactI18next)
      // init i18next
      // for all options read: https://www.i18next.com/overview/configuration-options
      .init({
        fallbackLng: 'en-US',
        resources: locales,
        debug: debugMode,
        keySeparator: false,
        interpolation: {
          escapeValue: false, // not needed for react as it escapes by default
        },
        detection,
        react: {
          wait: true,
        },
      });
  }

  return initialized.then(function(t) {
    i18n.T = t;
    customDebug(`T function available.`, 'info');
  });
}

customDebug(`version ${pkg.version} loaded.`, 'info');

i18n.initializing = initI18n();
i18n.initI18n = initI18n;
i18n.addLocales = addLocales;

export default i18n;
