import { Inject, Injectable, Optional } from '@angular/core';
import { log } from '@bixi/core/utils';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { BehaviorSubject, Observable } from 'rxjs';
import zh_CN from '../langs/zh-CN';
import { BIXI_I18N } from './i18n.token';
import { II18nConfig } from './i18n.type';
import { getValue } from './i18n.util';

@Injectable({
  providedIn: 'root'
})
export class BixiI18nService {
  private _locale!: II18nConfig;
  private _change = new BehaviorSubject<II18nConfig>(this._locale);

  get localeChange(): Observable<II18nConfig> {
    return this._change.asObservable();
  }

  constructor(
    @Optional() @Inject(BIXI_I18N) locale: II18nConfig) {
    this.setLocale(locale || zh_CN);
  }

  setLocale(locale: II18nConfig): void {
    if (this._locale && this._locale.locale === locale.locale) {
      return;
    }
    this._locale = locale;
    this._change.next(locale);
  }

  getLocale(): II18nConfig {
    return this._locale;
  }

  getLocaleId(): string {
    return this._locale ? this._locale.locale : '';
  }

  getLocaleData(path: string, keyValue?: NzSafeAny): NzSafeAny {
    let result = path ? getValue(this._locale, path) : this._locale;

    if (!result) {
      log(`[@bixi/core/i18n] failed to translate ${path}，you can checkout bixiI18nService.setLocale.`);
    }

    if (typeof result === 'string') {
      if (keyValue) {
        Object.keys(keyValue).forEach(key => {
          result = result.replace(new RegExp(`\\$\{${key}\}`, 'g'), keyValue[key]);
        });
      }
      return result;
    }
    return result || path;
  }
}
