import { catchError, first, map } from "rxjs/operators";
import { Observable, of } from "rxjs";
import { IEnSrvOptions } from "./IEnSrvOptions";
import { read } from "./read";
import moment from "moment-timezone";
import { isArray } from "lodash";

export interface ILocale {
  lang: string;
  timezone: string;
  dateFormat: string;
  datetimeFormat: string;
}

export function locale(enSrvOptions: IEnSrvOptions): Observable<ILocale> {
  if (enSrvOptions.locale) {
    return of(enSrvOptions.locale);
  }
  return read("app/locale", enSrvOptions).pipe(
    first(),
    map((localeEno) => {
      enSrvOptions.locale = {
        lang: localeEno.getFieldStringValue("app/type/locale:locale-id"),
        timezone: localeEno.getFieldStringValue("app/type/locale:timezone"),
        dateFormat: localeEno.getFieldStringValue("app/type/locale:dateformat"),
        datetimeFormat: localeEno.getFieldStringValue(
          "app/type/locale:datetimeformat"
        ),
      };
      return enSrvOptions.locale;
    })
  );
}

export function nowVar(enSrvOptions: IEnSrvOptions): Observable<string> {
  return locale(enSrvOptions).pipe(
    map((locale) => locale.timezone),
    catchError((err) => of("UTC")),
    map((timezone) => moment().tz(timezone).format("YYYY-MM-DDTHH:mm:ssZZ"))
  );
}

// Returns the language preferences for a given namespace
// If a lang is provided it is considered the first preference, then the system locale language,
// then en-us as a last resort.
export function getLangs(
  enSrvOptions: IEnSrvOptions,
  lang?: string | string[],
  includeFallbackLang: boolean = true
): Observable<string[]> {
  const langs: string[] = [];
  if (lang) {
    if (isArray(lang)) {
      lang.forEach((val) => langs.push(val));
    } else {
      langs.push(lang);
    }
  }
  return includeFallbackLang
    ? locale(enSrvOptions).pipe(
        map((locale) => locale.lang),
        catchError((err) => of("en-us")),
        map((systemLang) => {
          if (langs.indexOf(systemLang) === -1) {
            langs.push(systemLang);
          }
          if (langs.indexOf("en-us") === -1) {
            langs.push("en-us");
          }
          return langs;
        })
      )
    : of(langs);
}
