import {
  Component,
  OnInit,
  OnDestroy,
  ChangeDetectionStrategy,
  Input,
  Output,
  EventEmitter,
  ChangeDetectorRef
} from '@angular/core';
import { Dictionary } from '@ngrx/entity';
import { Store, select } from '@ngrx/store';
import { combineLatest, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

import { RoomSelector, RoomActions } from '@ucap/ng-store-chat';
import {
  LoginSelector,
  ConfigurationSelector
} from '@ucap/ng-store-authentication';
import {
  RoomUserMap,
  RoomUserShortMap
} from '@ucap/ng-store-chat/lib/store/room/state';
import { LoginResponse } from '@ucap/protocol-authentication';
import { RoomInfo, RoomType, UpdateRequest } from '@ucap/protocol-room';

import {
  TranslatePipe as OrganizationTranslate,
  TranslateService
} from '@ucap/ng-ui-organization';

import { AppChatService } from '@app/services/app-chat.service';
import { I18nService } from '@ucap/ng-i18n';
import { VersionInfo2Response } from '@ucap/api-public';
import { LocaleCode } from '@ucap/core';

@Component({
  selector: 'app-sections-chat-info',
  templateUrl: './info.section.component.html',
  styleUrls: ['./info.section.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class InfoSectionComponent implements OnInit, OnDestroy {
  @Input()
  set roomId(roomId: string) {
    this._roomId = roomId;

    // request selected room
    if (!!this.roomId) {
      this.store.dispatch(
        RoomActions.selectedRoom({
          roomId: this.roomId,
          localeCode: LocaleCode.Korean
        })
      );
    }

    this.getRoomInfo();
  }
  get roomId(): string {
    return this._roomId;
  }
  // tslint:disable-next-line: variable-name
  _roomId: string;

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

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

  versionInfo2Res: VersionInfo2Response;
  loginRes: LoginResponse;

  defaultProfileImage: string;
  defaultProfileImageMulti: string;

  currentRoomInfo: RoomInfo;
  roomList: RoomInfo[];
  roomUsersDictionary: Dictionary<RoomUserMap>;
  roomUsersShortDictionary: Dictionary<RoomUserShortMap>;

  roomName: string;
  roomImage: string;

  RoomType = RoomType;
  organizationTranslate: OrganizationTranslate;
  private ngOnDestroySubject: Subject<boolean>;

  constructor(
    private store: Store<any>,
    private appChatService: AppChatService,
    private i18nService: I18nService,
    private translateService: TranslateService,
    private changeDetectorRef: ChangeDetectorRef
  ) {
    // language setting
    this.translateService.setDefaultLang(this.i18nService.currentLng);
    this.translateService.use(this.i18nService.currentLng);
    this.organizationTranslate = new OrganizationTranslate(
      this.translateService,
      this.changeDetectorRef
    );

    // default image setting
    this.defaultProfileImage = this.appChatService.defaultProfileImage;
    this.defaultProfileImageMulti = this.appChatService.defaultProfileImage;
  }

  ngOnInit(): void {
    this.ngOnDestroySubject = new Subject<boolean>();

    this.store
      .pipe(
        takeUntil(this.ngOnDestroySubject),
        select(ConfigurationSelector.versionInfo2Response)
      )
      .subscribe((versionInfo2Res) => {
        this.versionInfo2Res = versionInfo2Res;
      });

    combineLatest([
      this.store.pipe(select(LoginSelector.loginRes)),
      this.store.pipe(select(RoomSelector.rooms)),
      this.store.pipe(
        select(
          (state: any) =>
            state.chat.room.roomUsers.entities as Dictionary<RoomUserMap>
        )
      ),
      this.store.pipe(
        select(
          (state: any) =>
            state.chat.room.roomUsersShort.entities as Dictionary<
              RoomUserShortMap
            >
        )
      )
    ])
      .pipe(takeUntil(this.ngOnDestroySubject))
      .subscribe(([loginRes, rooms, roomUsers, roomUsersShort]) => {
        this.loginRes = loginRes;
        if (!!loginRes && !!this.roomId) {
          this.roomList = rooms;
          this.roomUsersDictionary = roomUsers;
          this.roomUsersShortDictionary = roomUsersShort;

          this.getRoomInfo();
        }
      });
  }

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

  getRoomInfo(): void {
    // room render.
    if (!this.roomList || this.roomList.length === 0) {
      return;
    }

    this.roomName = '...';
    const idx = this.roomList.findIndex(
      (roomInfo) => roomInfo.roomId === this.roomId
    );
    if (idx > -1 && !!this.roomList && this.roomList.length > 0) {
      this.currentRoomInfo = this.roomList[idx];
    }

    if (!!this.currentRoomInfo) {
      // Setting RoomName.
      this.roomName = this.appChatService.getRoomName(
        this.organizationTranslate,
        this.loginRes,
        this.currentRoomInfo,
        this.roomUsersDictionary,
        this.roomUsersShortDictionary
      );

      this.roomImage = this.appChatService.getRoomProfileImage(
        this.currentRoomInfo,
        this.loginRes,
        this.roomUsersDictionary,
        this.roomUsersShortDictionary
      );
    }
    this.changeDetectorRef.detectChanges();
  }

  onToggleAlarm(roomInfo: RoomInfo): void {
    if (!roomInfo) {
      return;
    }

    this.store.dispatch(
      RoomActions.update({
        req: {
          roomId: roomInfo.roomId,
          roomName:
            roomInfo.roomName.trim().length === 0
              ? ' '
              : roomInfo.roomName.trim(),
          receiveAlarm: !roomInfo.receiveAlarm,
          syncAll: false
        } as UpdateRequest
      })
    );
    this.changeDetectorRef.detectChanges();
  }

  onOpenRoomUserList(roomInfo: RoomInfo): void {}

  onOpenChatSearch(): void {
    this.openChatSearch.emit();
  }

  onRightDrawerToggle(): void {
    this.rightDrawerToggle.emit();
  }
}
