import { inject } from 'aurelia-framework';
import { Router } from 'aurelia-router';
import { EntityManager } from './entity-manager';
import { CustomLogger } from '../modules/custom-logger';
import * as breeze from 'breeze-client';
import { UserProfile, Language } from '../model/common-model';
import { Config } from '../config';
import { HttpClient, json } from 'aurelia-fetch-client';
import { I18N } from 'aurelia-i18n';
import { EventAggregator } from 'aurelia-event-aggregator';

@inject(EntityManager, CustomLogger, Config, Router, HttpClient, I18N, EventAggregator)
export class Datacontext {
  constructor(private entityManager: EntityManager, private logger: CustomLogger, private config: Config, private router: Router, private httpClient: HttpClient, private i18n: I18N, private eventAggregator: EventAggregator) {
    eventAggregator.subscribe('i18n:locale:changed', async (data) => {
      await this.changeCurrentLangage();
    });
  }
  public currentLanguage: Language;
  public get translatePropertyName() {
    return `lang${this.currentLanguage.columnIndex}`;
  }
  public async primeData() {
    await Promise.all(
      [
        this.corePrimeData()
        //this.getCurrentUserProfile(config)
      ]);
    await this.changeCurrentLangage();
  }
  async changeCurrentLangage() {
    if (this.config.globalConfig.configuredLanguages != null) {
      let currentLocale = this.i18n.getLocale();
      if (currentLocale == null) currentLocale = "fr";

      this.currentLanguage = this.config.globalConfig.configuredLanguages.find(l => l.code.toLocaleLowerCase() == currentLocale);
      await this.saveUserLanguage();
    }
  }
  private corePrimeData() {
    return breeze.EntityQuery.from("PrimeData")
      .using(this.entityManager.manager)
      .execute()
      .then((data) => {
        this.config.globalConfig.configuredLanguages = (<any>data.results[0]).languages;
        return data;
      }).catch(this.queryFailed);
  }
  public getDistinctPropertyValues(tableName: string, propertyName: string, includeNullValue = true) {
    return breeze.EntityQuery.from("DistinctPropertyValues")
      .withParameters({ tableName, propertyName, includeNullValue })
      .using(this.entityManager.manager)
      .execute()
      .then((data) => {
        return data.results;
      })
      .catch((reason) => this.queryFailed(reason));
  }

  public async getCurrentUserProfile() {
    try {
      let data = await breeze.EntityQuery.from("GetCurrentUser")
        .using(this.entityManager.manager)
        .execute();

      return new UserProfile(data.results[0]);

    }
    catch (reason) {
      this.queryFailed(reason);
    }
  }

  private queryFailed(error) {
    var msg = this.i18n.tr('clientExceptions.errorRetreivingData', { ns: "common" }) + ": " + error.message;
    this.logError(msg, error);
    return null;
  }
  private log(msg: string, data: any, showToast: boolean) {
    this.logger.Log(msg, data, "Datacontext", showToast);
  }
  private logError(msg, error) {
    this.logger.LogError(msg, error, "Datacontext", true);
  }

  async saveUserSettings(userProfile: UserProfile) {
    sessionStorage.setItem(`user-settings-${userProfile.id}`, JSON.stringify(userProfile.sanitizedSettings));

    try {
      await this.httpClient
        .fetch(`${this.config.globalConfig.breezeControllerUri}/SaveUserSettings`, {
          method: 'post',
          body: json(userProfile.sanitizedSettings),
          headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Accept': 'application/json'
          }
        });
      this.log('user settings saved successfully', null, false);
    } catch (error) {
      this.log('user settings not saved', error, false);
    }
  }

  async saveUserLanguage() {
    let body = json(this.i18n.getLocale());

    try {
      await this.httpClient
        .fetch(`${this.config.globalConfig.breezeControllerUri}/SaveUserLanguage`, {
          method: 'post',
          body: body,
          headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Accept': 'application/json'
          }
        });
      this.log('user language saved successfully', null, false);
    }
    catch (error) {
      this.log('user language not saved', error, false);
    }
  }
}
