import {
  Component,
  OnInit,
  ChangeDetectorRef,
  Output,
  EventEmitter,
  Input,
  ViewChild,
  OnDestroy
} from '@angular/core';

import moment from 'moment';
import 'moment-timezone';

import {
  MatTabChangeEvent,
  MatTabGroup,
  MatCheckboxChange,
  MatSelectChange
} from '@angular/material';
import { GeneralSetting } from '../models/settings';
import { NGXLogger } from 'ngx-logger';
import { TranslateService } from '@ngx-translate/core';
import { take } from 'rxjs/operators';
import { Subscription, merge } from 'rxjs';

export interface TimezoneData {
  displayName: string;
  name: string;
}

export interface LanguageData {
  displayName: string;
  name: string;
}

@Component({
  selector: 'ucap-settings-general',
  templateUrl: './general.component.html',
  styleUrls: ['./general.component.scss']
})
export class GeneralComponent implements OnInit, OnDestroy {
  @Input()
  setting: GeneralSetting;

  @Output()
  changed = new EventEmitter<GeneralSetting>();

  @ViewChild('themeTabGroup', { static: true })
  themeTabGroup: MatTabGroup;

  get timezoneList(): TimezoneData[] {
    return this._timezoneList;
  }
  set timezoneList(timezoneList: TimezoneData[]) {
    this._timezoneList = timezoneList;
  }
  // tslint:disable-next-line: variable-name
  _timezoneList: TimezoneData[];

  get languageList(): LanguageData[] {
    return this._languageList;
  }
  set languageList(languageList: LanguageData[]) {
    this._languageList = languageList;
  }
  // tslint:disable-next-line: variable-name
  _languageList: LanguageData[];

  langChangeSubscription: Subscription;

  constructor(
    private translateService: TranslateService,
    private changeDetectorRef: ChangeDetectorRef,
    private logger: NGXLogger
  ) {
    moment.locale('ko');
  }

  ngOnInit() {
    this.logger.debug('general setting', this.setting);
    let themeIndex: number;
    switch (this.setting.appTheme) {
      case 'theme-default':
        themeIndex = 0;
        break;
      case 'theme-lgRed':
        themeIndex = 1;
        break;
      default:
        themeIndex = 0;
        break;
    }
    this.themeTabGroup.selectedIndex = themeIndex;

    this.setTimezoneData();
    this.setLanguageData();

    this.langChangeSubscription = merge(
      this.translateService.onLangChange,
      this.translateService.onDefaultLangChange,
      this.translateService.onTranslationChange
    ).subscribe(() => {
      this.setTimezoneData();
      this.setLanguageData();
    });
  }

  ngOnDestroy(): void {
    if (!!this.langChangeSubscription) {
      this.langChangeSubscription.unsubscribe();
    }
  }

  onSelectedTabChange(e: MatTabChangeEvent) {
    let theme = 'theme-default';
    switch (e.index) {
      case 0:
        theme = 'theme-default';
        break;
      case 1:
        theme = 'theme-lgRed';
        break;
      default:
        break;
    }

    this.emit({ ...this.setting, appTheme: theme });
  }

  onChangeAutoStart(event: MatCheckboxChange) {
    this.emit({ ...this.setting, autoLaunch: event.checked });
  }

  onChangeStartupHideWindow(event: MatCheckboxChange) {
    this.emit({ ...this.setting, startupHideWindow: event.checked });
  }

  onChangeContinueRunWhenClose(event: MatCheckboxChange) {
    this.emit({ ...this.setting, continueRunWhenClose: event.checked });
  }

  onChangeAutoLogin(event: MatCheckboxChange) {
    this.emit({ ...this.setting, autoLogin: event.checked });
  }

  onSelectionChangeLocale(event: MatSelectChange) {
    this.emit({ ...this.setting, locale: event.value });
  }

  onSelectionChangeHrInfoLocale(event: MatSelectChange) {
    this.emit({ ...this.setting, hrInfoLocale: event.value });
  }

  onSelectionChangeTimezone(event: MatSelectChange) {
    this.emit({ ...this.setting, timezone: event.value });
  }

  private emit(setting: GeneralSetting) {
    this.setting = setting;
    this.changed.emit(this.setting);
  }

  private setTimezoneData() {
    const timezoneData = this.translateService.instant('common.timezone');

    let timezoneList: TimezoneData[] = [];
    for (const name of moment.tz.names()) {
      const displayName = `(UTC${moment.tz(name).format('Z')}) ${
        timezoneData[name]
      }`;
      timezoneList.push({
        displayName,
        name
      });
    }
    timezoneList = timezoneList.sort((a: TimezoneData, b: TimezoneData) => {
      return a.displayName.localeCompare(b.displayName);
    });

    this.timezoneList = timezoneList;
  }

  private setLanguageData() {
    const languageData = this.translateService.instant('common.languages');

    const languageList: LanguageData[] = [];
    for (const key in languageData) {
      if (languageData.hasOwnProperty(key)) {
        languageList.push({ displayName: languageData[key], name: key });
      }
    }

    this.languageList = languageList;
  }
}
