import { Injectable } from '@angular/core';
import { ConfigService } from '../config/config.service';
import { clearTranslations, loadTranslations } from '@angular/localize';
import { registerLocaleData } from '@angular/common';
import { HttpClient } from '@angular/common/http';

const localeBaseFilesPath = 'assets/locale/';
const REPLACE_STRINGS_MARKER = 'en-replace';

const rtlLanguages = {
  ae: 'Avestan',	/* Avestan */
  ar: 'Arabic',   /* 'العربية', Arabic */
  arc: 'Aramaic',  /* Aramaic */
  bcc: 'Southern Balochi',  /* 'بلوچی مکرانی', Southern Balochi */
  bqi: 'Bakthiari',  /* 'بختياري', Bakthiari */
  ckb: 'Soranî',  /* 'Soranî / کوردی', Sorani */
  dv: 'Dhivehi',   /* Dhivehi */
  fa: 'Persian',   /* 'فارسی', Persian */
  glk: 'Gilaki',  /* 'گیلکی', Gilaki */
  he: 'Hebrew',   /* 'עברית', Hebrew */
  ku: 'Kurdî',   /* 'Kurdî / كوردی', Kurdish */
  mzn: 'Mazanderani',  /* 'مازِرونی', Mazanderani */
  nqo: 'N\'Ko',  /* N'Ko */
  pnb: 'Western Punjabi',  /* 'پنجابی', Western Punjabi */
  ps: 'Pashto',   /* 'پښتو', Pashto, */
  sd: 'Sindhi',   /* 'سنڌي', Sindhi */
  ug: '\'Uyghurche',   /* 'Uyghurche / ئۇيغۇرچە', Uyghur */
  ur: 'Urdu',   /* 'اردو', Urdu */
  yi: 'Yiddish',    /* 'ייִדיש', Yiddish */
  prs: 'Dari',    /* Dari, Afghan Persian */
};

@Injectable({
  providedIn: 'root'
})
export class LanguageService {
  private userLanguageCode: string;
  private stringsReplaced = false;
  public langDirection = 'ltr' as any;

  constructor(
    private config: ConfigService,
    private httpClient: HttpClient,
  ) {
  }

  setUserLanguage(languageCode: string) {
    if (!languageCode) {
      languageCode = this.config.current.settings.defaultLanguage;
    }
    let updateTranslations = false;
    const defaultLanguageChanged = this.config.current.settings.defaultLanguage !== 'en';
    let replaceStrings = false;
    if (this.config.current.settings.defaultLanguage === REPLACE_STRINGS_MARKER) {
      replaceStrings = true;
    }
    if (this.userLanguageCode !== languageCode &&
      ((languageCode !== this.config.current.settings.defaultLanguage) || defaultLanguageChanged)) {
      // update translations only when userLanguageCode will be updated and is different
      // than defaultLanguage (or default language was changed)
      updateTranslations = true;
    }
    if (defaultLanguageChanged && languageCode === 'en') {
      // the app uses english as default text, should simply load no translation file
      updateTranslations = false;
      if (this.userLanguageCode && this.userLanguageCode !== languageCode && !replaceStrings) {
        // do not clear translations if we replace default en strings
        clearTranslations();
      }
    }
    this.userLanguageCode = languageCode;
    if (rtlLanguages.hasOwnProperty(this.userLanguageCode)) {
      document.dir = 'rtl';
      this.langDirection = 'rtl';
    } else {
      document.dir = 'ltr';
      this.langDirection = 'ltr';
    }
    if (updateTranslations) {
      this.loadTranslationFiles(this.userLanguageCode).then((data) => {
        loadTranslations(data.translations);
      }).catch(() => {
        console.error(`Could not find translation files for ${this.userLanguageCode} language code.`);
      });
      // Workaround for bug described here https://github.com/angular/angular-cli/issues/22088
      // and here https://github.com/webpack/webpack/issues/13865 so that we can upgrade angular
      // to v. 13. Should be replaced with the following when possible:
      // const localeJs = `@angular/common/locales/global/${this.userLanguageCode}.js`;
      import(`../../../../node_modules/@angular/common/locales/${this.userLanguageCode}.mjs`).then(lang => {
        registerLocaleData(lang.default);
        this.config.locale = this.userLanguageCode;
      });
    } else if (replaceStrings && !this.stringsReplaced) {
      this.loadTranslationFiles(REPLACE_STRINGS_MARKER).then((data) => {
        loadTranslations(data.translations);
        this.stringsReplaced = true;
      }).catch(() => {
        console.error(`Could not find json file for replacing strings.`);
      });
    }
  }

  clearUserLanguage() {
    this.userLanguageCode = undefined;
    clearTranslations();
  }

  loadTranslationFiles(languageCode: string): Promise<any> {
    const fileUrl = `${localeBaseFilesPath}messages.${languageCode}.json`;
    return this.httpClient.get(fileUrl).toPromise();
  }

  public isRtlLanguage(): boolean {
    return rtlLanguages.hasOwnProperty(this.getCurrentLanguage());
  }

  getCurrentLanguage(): string {
    let languageCode = this.userLanguageCode;

    if (!languageCode) {
      if (this.config.current && this.config.current.settings) {
        languageCode = this.config.current.settings.defaultLanguage;
      }
    }

    return languageCode;
  }
}
