import { Inject, Injectable, Optional, Provider, SkipSelf } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

import zhCN from './languages/zh-CN';
import { OHAYO_LOCALE } from './locale.tokens';
import { FullLocaleData, LocaleData } from './locale.types';

@Injectable()
export class OhayoLocaleService {
  private _locale: FullLocaleData = zhCN;
  private change$ = new BehaviorSubject<FullLocaleData>(this._locale);

  constructor(@Inject(OHAYO_LOCALE) locale: FullLocaleData | null) {
    this.setLocale(locale || zhCN);
  }

  get change(): Observable<FullLocaleData> {
    return this.change$.asObservable();
  }

  setLocale(locale: FullLocaleData): void {
    if (this._locale && this._locale.abbr === locale.abbr) {
      return;
    }
    this._locale = locale;
    this.change$.next(locale);
  }

  get locale(): FullLocaleData {
    return this._locale;
  }

  getData(path: keyof FullLocaleData): LocaleData {
    return (this._locale[path] || {}) as LocaleData;
  }
}

export function OHAYO_LOCALE_SERVICE_PROVIDER_FACTORY(exist: OhayoLocaleService, locale: FullLocaleData): OhayoLocaleService {
  return exist || new OhayoLocaleService(locale);
}

export const OHAYO_LOCALE_SERVICE_PROVIDER: Provider = {
  provide: OhayoLocaleService,
  useFactory: OHAYO_LOCALE_SERVICE_PROVIDER_FACTORY,
  deps: [[new Optional(), new SkipSelf(), OhayoLocaleService], OHAYO_LOCALE],
};
