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

import { Subject, combineLatest, merge } from 'rxjs';
import { Store, select } from '@ngrx/store';
import { takeUntil } from 'rxjs/operators';

import { LoginResponse } from '@ucap/protocol-authentication';
import {
  RoomInfo,
  UpdateRequest,
  UpdateTimerSetRequest
} from '@ucap/protocol-room';
import { RoomSelector, RoomActions } from '@ucap/ng-store-chat';
import { LoginSelector } from '@ucap/ng-store-authentication';
import { I18nService } from '@ucap/ng-i18n';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-drawer-chat-setting',
  templateUrl: './setting.drawer.component.html',
  styleUrls: ['./setting.drawer.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class SettingDrawerComponent implements OnInit, OnDestroy {
  private roomIdSubject = new Subject<string>();
  private ngOnDestroySubject = new Subject<boolean>();

  @Input()
  set roomId(value: string) {
    this._roomId = value;
    this.roomIdSubject.next(value);
    this._initializeData();
  }
  get roomId(): string {
    return this._roomId;
  }
  // tslint:disable-next-line: variable-name
  _roomId: string;

  @Output()
  closed = new EventEmitter<void>();

  loginRes: LoginResponse;
  roomInfo: RoomInfo;

  roomName: string;
  timerArray: { value: number; text: string }[];

  chatSettingForm: FormGroup;

  constructor(
    private i18nService: I18nService,
    private store: Store<any>,
    private formBuilder: FormBuilder,
    private changeDetectorRef: ChangeDetectorRef
  ) {}

  ngOnInit(): void {
    this._initializeData();

    this.i18nService.languageChanged$
      .pipe(takeUntil(this.ngOnDestroySubject))
      .subscribe((_) => {
        this.setTimerArray();
      });
    this.setTimerArray();
  }

  ngOnDestroy(): void {
    if (!!this.ngOnDestroySubject) {
      this.ngOnDestroySubject.next();
      this.ngOnDestroySubject.complete();
    }
  }

  private _initializeData() {
    combineLatest([
      this.store.pipe(select(LoginSelector.loginRes)),
      this.store.pipe(select(RoomSelector.room, this.roomId))
    ])
      .pipe(takeUntil(merge(this.ngOnDestroySubject, this.roomIdSubject)))
      .subscribe(([loginRes, roomInfo]) => {
        this.loginRes = loginRes;
        this.roomInfo = roomInfo;

        this.chatSettingForm = this.formBuilder.group({
          roomName: [
            this.roomInfo?.roomName,
            !this.roomInfo?.isTimeRoom ? [Validators.required] : []
          ],
          changeTarget: ['me'],
          timerInterval: [this.roomInfo?.timeRoomInterval]
        });

        this.changeDetectorRef.detectChanges();
      });
  }

  onChange() {
    const checkInvalid = this.chatSettingForm.invalid;
    let roomName: string;
    if (checkInvalid) {
      roomName = '';
    } else {
      roomName = this.chatSettingForm.get('roomName').value;
    }
  }

  onKeyupName() {
    this.chatSettingForm.get('roomName').markAsTouched();
  }

  setTimerArray() {
    const hourFrom = this.i18nService.t('common:units.hourFrom');
    const minute = this.i18nService.t('common:units.minute');
    const second = this.i18nService.t('common:units.second');

    this.timerArray = [
      { value: 5, text: `5 ${second}` },
      { value: 10, text: `10 ${second}` },
      { value: 30, text: `30 ${second}` },
      { value: 60, text: `1 ${minute}` },
      { value: 300, text: `5 ${minute}` },
      { value: 600, text: `10 ${minute}` },
      { value: 1800, text: `30 ${minute}` },
      { value: 3600, text: `1 ${hourFrom}` },
      { value: 21600, text: `6 ${hourFrom}` },
      { value: 43200, text: `12 ${hourFrom}` },
      { value: 86400, text: `24 ${hourFrom}` }
    ];
  }

  onChangeGroupName(name: string) {
    this.roomName = name;
  }

  onClosed(event: MouseEvent): void {
    this.closed.emit();
  }

  const forbidden = /[\{\}\[\]\/?.;:|\)*~`!^+<>@\#$%&\\\=\(\'\"]/g.test(
        inputValue
      );

  onConfirm(): void {
    const roomName = this.chatSettingForm.get('roomName').value;
    const roomNameChangeTarget = this.chatSettingForm.get('changeTarget').value;
    const timerInterval = this.chatSettingForm.get('timerInterval').value;

    this.store.dispatch(
      RoomActions.update({
        req: {
          roomId: this.roomInfo.roomId,
          roomName,
          receiveAlarm: this.roomInfo.receiveAlarm,
          syncAll: roomNameChangeTarget.toUpperCase() === 'ALL' ? true : false
        } as UpdateRequest
      })
    );

    if (!!this.roomInfo?.isTimeRoom) {
      this.store.dispatch(
        RoomActions.updateTimeRoomInterval({
          req: {
            roomId: this.roomInfo.roomId,
            timerInterval
          } as UpdateTimerSetRequest
        })
      );
    }

    this.closed.emit();
  }
}