export class I18n {
  constructor(appState) {
    this.appState = appState;
    this.availableLanguages = null;
    this.language = null;
    this.default = null;
    this.pages = {};
  }

  get needsFetch () {
    return !this.availableLanguages && !this.language && !this.default;
  }

  fetchLocaleUI () {
    return fetch(`/locales/${this.appState.language}/ui`).then(response => response.json()).then(response => {
      this.availableLanguages = response.available;
      this.default = response.default;
      this.language = response.locale;
    }).catch(error => {
      console.error(error);
    });
  }

  fetchLocalePage (page) {
    return fetch(`/locales/${this.appState.language}/page/${page}`).then(response => response.text()).then(response => {
      this.pages[page] = response;
    }).catch(error => {
      console.error(error);
    });
  }

  translate (target, useDefault = false) {
    let language = useDefault ? this.default : this.language;
    const pieces = target.split('.');

    if (!this.needsFetch && !useDefault && this.appState.language !== language.locale) {
      console.warn(`The target language (${this.appState.language}) does not exist. Defaulting to ${this.default.name} (${this.default.locale}).`);
      language = this.default;
    }

    let translation = pieces.reduce((lang, piece, i) => {
      if (lang === false) return false;

      if (typeof lang[piece] === 'object') {
        // Only continue if there's another piece, otherwise, it will error.
        if (typeof pieces[i + 1] !== 'undefined') {
          return lang[piece];
        }
      }
      
      if (typeof lang[piece] === 'string') {
        return lang[piece];
      }

      return false;
    }, Object.assign({}, language));

    if (translation === false) {
      if (language.locale !== this.default.locale) {
        console.warn(`The translation for "${target}" is not set in the ${this.language.locale} locale. Using ${this.default.name} (${this.default.locale}) instead.`);
        return this.translate(target, true);
      }
      console.error(`The translation for "${target}" is set up in neither the target nor default locale.`);
      return target;
    }
    
    return translation;
  }
  
  __ (translation) {
    return this.translate(translation);
  }
}