import { Component, OnInit, Inject, Renderer2 } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { KEY_LOGIN_RES_INFO, KEY_VER_INFO } from '@app/types';
import {
  SessionStorageService,
  LocalStorageService
} from '@ucap-webmessenger/web-storage';

import { Store } from '@ngrx/store';

import clone from 'clone';

import {
  DialogService,
  TranslateService as UCapTranslateService,
  DateService as UCapDateService
} from '@ucap-webmessenger/ui';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { map, take } from 'rxjs/operators';
import { DOCUMENT } from '@angular/common';
import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type';
import {
  EnvironmentsInfo,
  KEY_ENVIRONMENTS_INFO
} from '@app/types/environment.type';
import { environment } from '../../../../../environments/environment';
import {
  GeneralSetting,
  Settings,
  NotificationSetting,
  ChatSetting
} from '@ucap-webmessenger/ui-settings';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { TranslateService } from '@ngx-translate/core';
import { ObjectUtil } from '@ucap-webmessenger/core';
import { OptionProtocolService } from '@ucap-webmessenger/protocol-option';

export interface MessengerSettingsDialogData {}

export interface MessengerSettingsDialogResult {}

@Component({
  selector: 'app-messenger-settings-dialog',
  templateUrl: './messenger-settings.dialog.component.html',
  styleUrls: ['./messenger-settings.dialog.component.scss']
})
export class MessengerSettingsDialogComponent implements OnInit {
  loginRes: LoginResponse;
  sessionVerinfo: VersionInfo2Response;
  environmentsInfo: EnvironmentsInfo;

  modifiedSettings: Settings;

  appUserInfo: AppUserInfo;

  constructor(
    public dialogRef: MatDialogRef<
      MessengerSettingsDialogData,
      MessengerSettingsDialogResult
    >,
    @Inject(MAT_DIALOG_DATA) public data: MessengerSettingsDialogData,
    private dialogService: DialogService,
    private sessionStorageService: SessionStorageService,
    private localStorageService: LocalStorageService,
    private ucapTranslateService: UCapTranslateService,
    private ucapDateService: UCapDateService,
    private optionProtocolService: OptionProtocolService,
    @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
    private translateService: TranslateService,
    private store: Store<any>,
    @Inject(DOCUMENT) private document: Document,
    private renderer2: Renderer2
  ) {
    this.appUserInfo = this.localStorageService.encGet<AppUserInfo>(
      KEY_APP_USER_INFO,
      environment.customConfig.appKey
    );

    this.modifiedSettings = clone(this.appUserInfo.settings);

    this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
      KEY_VER_INFO
    );
    this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
      KEY_ENVIRONMENTS_INFO
    );
    this.loginRes = this.sessionStorageService.get<LoginResponse>(
      KEY_LOGIN_RES_INFO
    );
  }

  ngOnInit() {}

  onChangedGeneralSetting(setting: GeneralSetting) {
    this.modifiedSettings = this.applySettings(this.modifiedSettings, {
      ...this.appUserInfo.settings,
      general: setting
    });
  }

  onChangedNotificationSetting(setting: NotificationSetting) {
    this.modifiedSettings = this.applySettings(this.modifiedSettings, {
      ...this.appUserInfo.settings,
      notification: setting
    });
  }

  onChangedChatSetting(setting: ChatSetting) {
    this.modifiedSettings = this.applySettings(this.modifiedSettings, {
      ...this.appUserInfo.settings,
      chat: setting
    });
  }

  onClickChoice(choice: boolean): void {
    if (choice) {
      if (
        !ObjectUtil.equals(this.appUserInfo.settings, this.modifiedSettings)
      ) {
        this.optionProtocolService
          .regUpdate({
            absenceTime: this.modifiedSettings.presence.absenceTime,
            deviceType: this.environmentsInfo.deviceType,
            fontFamily: this.modifiedSettings.chat.fontFamily,
            fontSize: this.modifiedSettings.chat.fontSize,
            hrInformationLanguage: this.modifiedSettings.general.hrInfoLocale,
            menuLanguage: this.modifiedSettings.general.locale,
            mobileNotification: this.modifiedSettings.notification
              .receiveForMobile,
            notificationExposureTime: this.modifiedSettings.notification
              .alertExposureTime,
            notificationMethod: this.modifiedSettings.notification.method,
            notificationMethod0: this.modifiedSettings.notification.method,
            receiveNotification: this.modifiedSettings.notification.use,
            timeZone: this.modifiedSettings.general.timezone,
            timeZoneValue: '0'
          })
          .pipe(take(1))
          .subscribe(res => {
            this.appUserInfo.settings = this.modifiedSettings;
            this.localStorageService.encSet<AppUserInfo>(
              KEY_APP_USER_INFO,
              this.appUserInfo,
              environment.customConfig.appKey
            );
          });
      }
    } else {
      this.applySettings(this.modifiedSettings, this.appUserInfo.settings);
    }

    this.dialogRef.close({});
  }

  private applySettings(
    oriSettings: Settings,
    modSettings: Settings
  ): Settings {
    if (oriSettings.general.appTheme !== modSettings.general.appTheme) {
      this.renderer2.setAttribute(
        this.document.body,
        'class',
        modSettings.general.appTheme
      );
    }
    if (oriSettings.general.locale !== modSettings.general.locale) {
      this.translateService.use(modSettings.general.locale);
    }
    if (oriSettings.general.hrInfoLocale !== modSettings.general.hrInfoLocale) {
      this.ucapTranslateService.use(modSettings.general.hrInfoLocale);
    }

    if (oriSettings.general.timezone !== modSettings.general.timezone) {
      this.ucapDateService.use(modSettings.general.timezone);
    }

    if (oriSettings.general.autoLaunch !== modSettings.general.autoLaunch) {
      this.nativeService.changeAutoLaunch(modSettings.general.autoLaunch);
    }
    if (
      oriSettings.general.startupHideWindow !==
      modSettings.general.startupHideWindow
    ) {
      this.nativeService.changeStartupHideWindow(
        modSettings.general.startupHideWindow
      );
    }

    if (oriSettings.chat.downloadPath !== modSettings.chat.downloadPath) {
      this.nativeService.changeDownloadPath(modSettings.chat.downloadPath);
    }

    return modSettings;
  }
}
