import {
  Component,
  OnInit,
  OnDestroy,
  ViewChild,
  AfterViewInit,
  Output,
  EventEmitter,
  Inject,
  ChangeDetectorRef,
  ChangeDetectionStrategy
} from '@angular/core';
import {
  ucapAnimations,
  SnackBarService,
  ClipboardService,
  DialogService,
  ConfirmDialogComponent,
  ConfirmDialogData,
  ConfirmDialogResult,
  AlertDialogComponent,
  AlertDialogData,
  AlertDialogResult,
  FileUploadQueueComponent,
  StringUtil,
  SelectFileInfo
} from '@ucap-webmessenger/ui';
import { Store, select } from '@ngrx/store';
import { NGXLogger } from 'ngx-logger';
import {
  Observable,
  Subscription,
  forkJoin,
  of,
  BehaviorSubject,
  combineLatest
} from 'rxjs';

import {
  Info,
  EventType,
  isRecalled,
  isCopyable,
  isRecallable,
  isForwardable,
  InfoResponse,
  EventJson,
  FileEventJson,
  StickerEventJson,
  MassTextEventJson,
  TranslationEventJson,
  MassTranslationEventJson
} from '@ucap-webmessenger/protocol-event';

import * as AppStore from '@app/store';
import * as EventStore from '@app/store/messenger/event';
import * as ChatStore from '@app/store/messenger/chat';
import * as RoomStore from '@app/store/messenger/room';
import * as SyncStore from '@app/store/messenger/sync';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import {
  SessionStorageService,
  LocalStorageService
} from '@ucap-webmessenger/web-storage';
import {
  EnvironmentsInfo,
  KEY_ENVIRONMENTS_INFO,
  UserSelectDialogType,
  RightDrawer,
  KEY_STICKER_HISTORY
} from '@app/types';
import {
  RoomInfo,
  UserInfo,
  RoomType,
  UserInfoShort
} from '@ucap-webmessenger/protocol-room';
import { take, map, catchError, tap } from 'rxjs/operators';
import {
  FormComponent as UCapUiChatFormComponent,
  MessagesComponent as UCapUiChatMessagesComponent
} from '@ucap-webmessenger/ui-chat';
import { KEY_VER_INFO } from '@app/types';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import {
  MatMenuTrigger,
  MatSnackBarRef,
  SimpleSnackBar,
  MatCheckbox
} from '@angular/material';
import { FileUploadItem, FileDownloadItem } from '@ucap-webmessenger/api';
import {
  CommonApiService,
  FileTalkSaveRequest,
  FileTalkSaveResponse,
  FileTalkSaveMultiRequest
} from '@ucap-webmessenger/api-common';
import {
  CreateChatDialogComponent,
  CreateChatDialogData,
  CreateChatDialogResult
} from '../dialogs/chat/create-chat.dialog.component';
import {
  FileViewerDialogComponent,
  FileViewerDialogData,
  FileViewerDialogResult
} from '@app/layouts/common/dialogs/file-viewer.dialog.component';
import { FileUtil, StickerFilesInfo } from '@ucap-webmessenger/core';

import { StatusCode } from '@ucap-webmessenger/api';
import {
  EditChatRoomDialogComponent,
  EditChatRoomDialogResult,
  EditChatRoomDialogData
} from '../dialogs/chat/edit-chat-room.dialog.component';
import {
  SelectGroupDialogComponent,
  SelectGroupDialogResult,
  SelectGroupDialogData
} from '../dialogs/group/select-group.dialog.component';
import { GroupDetailData } from '@ucap-webmessenger/protocol-sync';
import { environment } from '../../../../environments/environment';
import {
  MassDetailComponent,
  MassDetailDialogData
} from '../dialogs/chat/mass-detail.component';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { TranslateService } from '@ngx-translate/core';
import { TranslatePipe } from 'projects/ucap-webmessenger-ui/src/lib/pipes/translate.pipe';
import { TranslateService as UiTranslateService } from '@ucap-webmessenger/ui';

import {
  ClipboardDialogComponent,
  ClipboardDialogData,
  ClipboardDialogResult
} from '../dialogs/chat/clipboard.dialog.component';
import { AppFileService } from '@app/services/file.service';
import { FileInfo } from '@ucap-webmessenger/protocol-file';

@Component({
  selector: 'app-layout-messenger-messages',
  templateUrl: './messages.component.html',
  styleUrls: ['./messages.component.scss'],
  animations: ucapAnimations,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
  @Output()
  openProfile = new EventEmitter<{
    userSeq: number;
  }>();
  @Output()
  closeRightDrawer = new EventEmitter();

  @ViewChild('chatForm', { static: false })
  private chatForm: UCapUiChatFormComponent;

  @ViewChild('messageContextMenuTrigger', { static: true })
  messageContextMenuTrigger: MatMenuTrigger;
  messageContextMenuPosition = { x: '0px', y: '0px' };

  @ViewChild('fileUploadQueue', { static: true })
  fileUploadQueue: FileUploadQueueComponent;

  @ViewChild('chatMessages', { static: true })
  chatMessages: UCapUiChatMessagesComponent;

  @ViewChild('choiceBundleImage', { static: false })
  choiceBundleImage: MatCheckbox;

  environmentsInfo: EnvironmentsInfo;

  loginResSubscription: Subscription;
  loginResSubject = new BehaviorSubject<LoginResponse>(undefined);

  roomInfoSubscription: Subscription;
  roomInfoSubject = new BehaviorSubject<RoomInfo>(undefined);

  userInfoListSubscription: Subscription;
  userInfoListSubject = new BehaviorSubject<UserInfo[]>(undefined);

  eventListSubscription: Subscription;
  eventListSubject = new BehaviorSubject<Info<EventJson>[]>(undefined);
  eventListNewSubject = new BehaviorSubject<Info<EventJson>[]>(undefined);

  eventInfoStatusSubscription: Subscription;
  eventInfoStatusSubject = new BehaviorSubject<InfoResponse>(undefined);

  eventRemainedSubscription: Subscription;
  eventRemainedSubject = new BehaviorSubject<boolean>(false); // 이전대화가 남아 있는지 여부

  fileInfoListSubscription: Subscription;
  fileInfoListSubject = new BehaviorSubject<FileInfo[]>([]);

  lockSubject = new BehaviorSubject<boolean>(false);

  sessionVerInfo: VersionInfo2Response;

  baseEventSeq = 0;
  eventListProcessing$: Observable<boolean>;
  searchEventListProcessing: boolean;
  searchEventListProcessingSubscription: Subscription;

  isRecalledMessage = isRecalled;
  isCopyableMessage = isCopyable;
  isRecallableMessage = isRecallable;
  isForwardableMessage = isForwardable;

  /** Timer 대화방의 대화 삭제를 위한 interval */
  interval: any;

  /** About Searching */
  isShowSearchArea = false;
  moreSearchProcessing = false;
  searchText = '';
  searchedListSubject = new BehaviorSubject<Info<EventJson>[]>(undefined);
  searchedFocusEvent: Info<EventJson>;
  searchTotalCount = 0;
  searchCurrentIndex = 0;

  /** About Sticker */
  isShowStickerSelector = false;
  selectedSticker: StickerFilesInfo;

  /** 번역기능 비활성화 2020-02-07
   * About Translation
   **/
  // isTranslationProcess = false;
  // isShowTranslation = false;
  // translationSimpleview = false;
  // translationPreview = false;
  // destLocale = 'en'; // default English :: en
  // translationPreviewInfo: {
  //   previewInfo: TranslationSaveResponse | null;
  //   translationType: EventType.Translation | EventType.MassTranslation;
  // };

  /** About ReadHere */
  firstCheckReadHere = true;
  clearReadHere = false;
  initRoomLastEventSeq: number;
  isImageOnlyForFileUpload = false;
  bundleFileUploadItem: FileUploadItem;
  bundleFileUploadItems: FileUploadItem[];

  snackBarPreviewEvent: MatSnackBarRef<SimpleSnackBar>;

  RoomType = RoomType;
  environment = environment;

  constructor(
    private store: Store<any>,
    private sessionStorageService: SessionStorageService,
    private localStorageService: LocalStorageService,
    private commonApiService: CommonApiService,
    private clipboardService: ClipboardService,
    private uiTranslateService: UiTranslateService,
    private translateService: TranslateService,
    private changeDetectorRef: ChangeDetectorRef,
    private dialogService: DialogService,
    private snackBarService: SnackBarService,
    @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
    private appFileService: AppFileService,
    private logger: NGXLogger
  ) {
    this.sessionVerInfo = this.sessionStorageService.get<VersionInfo2Response>(
      KEY_VER_INFO
    );

    this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
      KEY_ENVIRONMENTS_INFO
    );
  }

  ngOnInit() {
    this.loginResSubscription = this.store
      .pipe(select(AppStore.AccountSelector.AuthenticationSelector.loginRes))
      .subscribe(loginRes => {
        this.loginResSubject.next(loginRes);
      });

    this.roomInfoSubscription = this.store
      .pipe(select(AppStore.MessengerSelector.RoomSelector.roomInfo))
      .subscribe(roomInfo => {
        if (
          !this.roomInfoSubject.value ||
          (!!this.roomInfoSubject.value &&
            !!roomInfo &&
            this.roomInfoSubject.value.roomSeq !== roomInfo.roomSeq)
        ) {
          this.clearView();

          if (!!this.roomInfoSubject.value && !!this.interval) {
            clearInterval(this.interval);
            this.interval = undefined;
          }

          if (
            !!this.roomInfoSubject.value &&
            !!this.roomInfoSubject.value.isTimeRoom
          ) {
            this.interval = setInterval(() => {
              this.store.dispatch(EventStore.infoIntervalClear({}));
            }, 1000);
          }

          this.readyToReply();
        }

        this.roomInfoSubject.next(roomInfo);
      });

    this.userInfoListSubscription = this.store
      .pipe(select(AppStore.MessengerSelector.RoomSelector.selectUserinfolist))
      .subscribe(userInfoList => {
        this.userInfoListSubject.next(userInfoList);
      });

    this.eventListProcessing$ = this.store.pipe(
      select(AppStore.MessengerSelector.EventSelector.infoListProcessing)
    );

    this.searchEventListProcessingSubscription = this.store
      .pipe(
        select(
          AppStore.MessengerSelector.EventSelector.infoSearchListProcessing
        )
      )
      .subscribe(process => {
        this.lockSubject.next(process);
        this.searchEventListProcessing = process;
        if (!process && this.isShowSearchArea) {
          this.doSearchTextInEvent(this.searchText);
          this.snackBarService.open(
            this.translateService.instant('chat.searchEventByTextEnd'),
            this.translateService.instant('common.messages.confirm'),
            {
              duration: 3000,
              verticalPosition: 'top',
              horizontalPosition: 'center'
            }
          );
        }
      });

    this.eventRemainedSubscription = this.store
      .pipe(select(AppStore.MessengerSelector.EventSelector.remainInfo))
      .subscribe(remained => {
        this.eventRemainedSubject.next(remained);
      });

    // [Daesang]
    this.eventListSubscription = this.store
      .pipe(select(AppStore.MessengerSelector.EventSelector.selectAllInfoList))
      .subscribe(infoList => {
        if (
          !!this.eventListSubject.value &&
          this.eventListSubject.value.length > 0
        ) {
          this.eventListNewSubject.next(
            infoList.filter(info => {
              if (
                info.seq <=
                this.eventListSubject.value[
                  this.eventListSubject.value.length - 1
                ].seq
              ) {
                return false;
              }
              return true;
            })
          );

          if (
            !!infoList &&
            infoList.length > 0 &&
            !!this.roomInfoSubject.value &&
            !!this.roomInfoSubject.value.lastReadEventSeq &&
            this.baseEventSeq <= this.roomInfoSubject.value.lastReadEventSeq
          ) {
            // 조회된 내용중에 read here 가 있을 경우.
            this.firstCheckReadHere = false;
          }
        }

        this.eventListSubject.next(infoList);

        if (this.moreSearchProcessing) {
          const baseseq = this.baseEventSeq;
          // setTimeout(() => {
          //   this.doSearchTextInEvent(this.searchText, baseseq);
          // }, 800);
          this.baseEventSeq = infoList[0].seq;
        } else {
          if (!!infoList && infoList.length > 0) {
            this.baseEventSeq = infoList[0].seq;
          }
        }
      });

    // // [GROUP]
    // this.eventListSubscription = this.store
    //   .pipe(
    //     select(AppStore.MessengerSelector.EventSelector.selectAllInfoList),
    //     tap(infoList => {
    //       if (!!this.eventList && this.eventList.length > 0) {
    //         this.eventListNew = infoList.filter(info => {
    //           if (info.seq <= this.eventList[this.eventList.length - 1].seq) {
    //             return false;
    //           }
    //           return true;
    //         });
    //       }
    //       this.eventList = infoList;

    //       if (!!infoList && infoList.length > 0) {
    //         this.baseEventSeq = infoList[0].seq;
    //         this.readyToReply();
    //       }
    //     })
    //   )
    //   .subscribe();

    this.eventInfoStatusSubscription = this.store
      .pipe(select(AppStore.MessengerSelector.EventSelector.infoStatus))
      .subscribe(res => {
        this.eventInfoStatusSubject.next(res);

        if (!!res) {
          const elist = this.eventListSubject.value;
          if (res.baseSeq === 0 && elist.length > 0) {
            this.initRoomLastEventSeq = elist[elist.length - 1].seq;
          }
        }
      });

    this.fileInfoListSubscription = combineLatest([
      this.store.pipe(select(AppStore.MessengerSelector.RoomSelector.roomInfo)),
      this.store.pipe(
        select(AppStore.MessengerSelector.EventSelector.selectAllFileInfoList)
      )
    ])
      .pipe(
        tap(() => {}),
        tap(([roomInfo, fileInfoList]) => {
          // tslint:disable-next-line: variable-name
          const _fileInfoList = fileInfoList.filter(fileInfo => {
            if (!!roomInfo && fileInfo.roomSeq === roomInfo.roomSeq) {
              return true;
            } else {
              return false;
            }
          });

          this.fileInfoListSubject.next(_fileInfoList);
        })
      )
      .subscribe();
  }

  ngOnDestroy(): void {
    if (!!this.loginResSubscription) {
      this.loginResSubscription.unsubscribe();
    }
    if (!!this.roomInfoSubscription) {
      this.roomInfoSubscription.unsubscribe();
    }
    if (!!this.userInfoListSubscription) {
      this.userInfoListSubscription.unsubscribe();
    }
    if (!!this.eventListSubscription) {
      this.eventListSubscription.unsubscribe();
    }
    if (!!this.eventInfoStatusSubscription) {
      this.eventInfoStatusSubscription.unsubscribe();
    }
    if (!!this.eventRemainedSubscription) {
      this.eventRemainedSubscription.unsubscribe();
    }
    if (!!this.searchEventListProcessingSubscription) {
      this.searchEventListProcessingSubscription.unsubscribe();
    }
    if (!!this.fileInfoListSubscription) {
      this.fileInfoListSubscription.unsubscribe();
    }

    if (!!this.interval) {
      clearInterval(this.interval);
    }
  }

  ngAfterViewInit(): void {
    // this.readyToReply();
  }

  /**
   * 채팅방의 여러 팝업들을 닫아준다.
   */
  clearView() {
    // Right Drawer closed..
    this.closeRightDrawer.emit();

    // Sticker Selector Clear..
    this.isShowStickerSelector = false;
    this.selectedSticker = undefined;

    // Chat Search Clear..
    this.onCloseSearchArea();

    // 번역기능 비활성화 2020-02-07
    // Translate Clear..
    // this.isTranslationProcess = false;
    // this.isShowTranslation = false;
    // this.translationSimpleview = false;
    // this.translationPreview = false;
    // this.destLocale = 'en'; // default English :: en
    // this.translationPreviewInfo = null;

    // Read here Clear..
    this.firstCheckReadHere = true;

    // Chat Formfield Clear..
    if (!!this.chatForm) {
      this.chatForm.replyInput.nativeElement.value = '';
    }
  }

  get _roomUserInfos() {
    if (this.roomInfoSubject.value.roomType === RoomType.Single) {
      return this.userInfoListSubject.value.filter(roomUserInfo => {
        return this.loginResSubject.value.userSeq !== roomUserInfo.seq;
      });
    } else {
      return this.userInfoListSubject.value
        .filter(roomUserInfo => {
          return (
            this.loginResSubject.value.userSeq !== roomUserInfo.seq &&
            roomUserInfo.isJoinRoom
          );
        })
        .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
    }
  }

  getRoomNameByRoomUser(roomUserInfos: (UserInfo | UserInfoShort)[]) {
    let roomName = new TranslatePipe(
      this.uiTranslateService,
      this.changeDetectorRef
    ).transform(roomUserInfos, 'name', ',');

    if (!roomName || roomName.trim().length === 0) {
      roomName = this.translateService.instant('chat.noRoomUser');
    }
    return roomName;
  }

  /** 대화전송 가능한 방인지 판단 */
  getEnableSend() {
    if (!this.roomInfoSubject.value) {
      return false;
    }

    if (
      [
        RoomType.Bot,
        RoomType.Allim,
        RoomType.Link,
        RoomType.Allim_Elephant,
        RoomType.Allim_TMS
      ].some(v => v === this.roomInfoSubject.value.roomType)
    ) {
      return false;
    }

    return true;
  }

  getConvertTimer(timerInterval: number, unit: number = 1) {
    if (timerInterval >= 0 && timerInterval < 60 * unit) {
      return Math.floor((timerInterval / 1) * unit) + ' 초';
    } else if (timerInterval >= 60 * unit && timerInterval < 3600 * unit) {
      return Math.floor(((timerInterval / 1) * unit) / 60) + ' 분';
    } else if (timerInterval >= 3600 * unit && timerInterval <= 86400 * unit) {
      return Math.floor(((timerInterval / 1) * unit) / 60 / 60) + ' 시간';
    } else {
      return '';
    }
  }

  getShowContextMenu(menuType: string) {
    if (
      ['OPEN_ROOM_USER', 'ADD_MEMBER', 'ADD_GROUP', 'EDIT_ROOM'].some(
        v => v === menuType
      )
    ) {
      if (
        !this.roomInfoSubject.value ||
        !this.roomInfoSubject.value.roomType ||
        [
          RoomType.Mytalk,
          RoomType.Allim,
          RoomType.Bot,
          RoomType.Link,
          RoomType.Allim_Elephant,
          RoomType.Allim_TMS
        ].some(v => v === this.roomInfoSubject.value.roomType)
      ) {
        return false;
      }
    }

    return true;
  }

  getShowUnreadCount(): boolean {
    if (
      !this.roomInfoSubject.value ||
      this.roomInfoSubject.value === undefined
    ) {
      return true;
    }
    if (
      [
        RoomType.Mytalk,
        RoomType.Allim,
        RoomType.Bot,
        RoomType.Link,
        RoomType.Allim_Elephant,
        RoomType.Allim_TMS
      ].some(v => v === this.roomInfoSubject.value.roomType)
    ) {
      return false;
    }

    return true;
  }

  readyToReply(): void {
    setTimeout(() => {
      this.focusReplyInput();
    });
  }

  focusReplyInput(): void {
    setTimeout(() => {
      if (!!this.chatForm) {
        this.chatForm.focus();
      }
    });
  }

  onScrollupMessages(event: any) {}
  onYReachStartMessages(event: any) {
    // 자동 스크롤이 아닌 버튼 방식으로 변경.
    // this.onMoreEvent(this.baseEventSeq);
  }
  onYReachEndMessages(event: any) {
    this.chatMessages.initEventMore();
    if (!!this.snackBarPreviewEvent) {
      this.snackBarPreviewEvent.dismiss();
    }

    // // clear readHere object.. 정책상 클리어 하지 않도록 함.
    // if (!this.firstCheckReadHere) {
    //   this.clearReadHere = true;
    // }
  }

  /** More Event */
  onMoreEvent(seq: number) {
    this.store.dispatch(
      EventStore.info({
        roomSeq: this.roomInfoSubject.value.roomSeq,
        baseSeq: seq,
        requestCount:
          environment.productConfig.CommonSetting.eventRequestDefaultCount
      })
    );
  }

  /** Send Event */
  async onSendMessage(message: string) {
    if (!!this.bundleFileUploadItems) {
      if (this.choiceBundleImage.checked) {
        await this.uploadBundleFile();
      } else {
        this.bundleFileUploadItem = undefined;
        await this.uploadFiles(this.bundleFileUploadItems).finally(() => {
          this.bundleFileUploadItems = undefined;
        });
      }
    }

    this.chatMessages.initEventMore();

    if (!this.selectedSticker) {
      if (!message || message.trim().length === 0) {
        // const result = await this.dialogService.open<
        //   AlertDialogComponent,
        //   AlertDialogData,
        //   AlertDialogResult
        // >(AlertDialogComponent, {
        //   width: '360px',
        //   data: {
        //     title: this.translateService.instant('chat.errors.label'),
        //     message: this.translateService.instant(
        //       'chat.errors.inputChatMessage'
        //     )
        //   }
        // });
        return;
      }
    }

    // 번역기능 비활성화 2020-02-07
    // if (!!this.isShowTranslation && this.destLocale.trim().length > 0) {
    //   /** CASE : Translation */
    //   // 번역할 대화 없이 스티커만 전송할 경우.
    //   if (!message || message.trim().length === 0) {
    //     this.sendMessageOfSticker(message);
    //   } else {
    //     this.sendMessageOfTranslate(message);
    //   }
    // } else

    if (!!this.selectedSticker) {
      /** CASE : Sticker */
      this.sendMessageOfSticker(message);
    } else if (
      message.trim().length >
      environment.productConfig.CommonSetting.masstextLength
    ) {
      /** CASE : MASS TEXT */
      this.sendMessageOfMassText(message);
    } else {
      /** CASE : Normal Text */
      this.sendMessageOfNormal(message);
    }
  }

  /** Send Normal message */
  sendMessageOfNormal(message: string) {
    this.store.dispatch(
      EventStore.send({
        senderSeq: this.loginResSubject.value.userSeq,
        req: {
          roomSeq: this.roomInfoSubject.value.roomSeq,
          eventType: EventType.Character,
          sentMessage: StringUtil.escapeHtml(message)
        }
      })
    );
  }
  /** Send Sticker message */
  async sendMessageOfSticker(message: string, isCheck: boolean = true) {
    if (
      !!isCheck &&
      !!message &&
      message.trim().length >
        environment.productConfig.CommonSetting.masstextLength
    ) {
      const result = await this.dialogService.open<
        AlertDialogComponent,
        AlertDialogData,
        AlertDialogResult
      >(AlertDialogComponent, {
        width: '360px',
        data: {
          title: this.translateService.instant('chat.errors.label'),
          message: this.translateService.instant(
            'chat.errors.maxLengthOfMassText',
            {
              maxLength: environment.productConfig.CommonSetting.masstextLength
            }
          )
        }
      });
      return;
    }

    const stickerJson: StickerEventJson = {
      name: '스티커',
      file: this.selectedSticker.index,
      chat: !!message ? StringUtil.escapeHtml(message.trim()) : ''
    };
    this.store.dispatch(
      EventStore.send({
        senderSeq: this.loginResSubject.value.userSeq,
        req: {
          roomSeq: this.roomInfoSubject.value.roomSeq,
          eventType: EventType.Sticker,
          sentMessage: JSON.stringify(stickerJson)
        }
      })
    );
    this.isShowStickerSelector = false;
    this.setStickerHistory(this.selectedSticker);
    this.selectedSticker = null;
  }
  /** Send Masstext message */
  sendMessageOfMassText(message: string) {
    this.store.dispatch(
      EventStore.sendMass({
        senderSeq: this.loginResSubject.value.userSeq,
        req: {
          roomSeq: this.roomInfoSubject.value.roomSeq,
          eventType: EventType.MassText,
          // sentMessage: message.replace(/\n/gi, '\r\n')
          sentMessage: StringUtil.escapeHtml(message)
        }
      })
    );
  }
  /**
   * 번역기능 비활성화 2020-02-07
   * Send Translation message
   **/
  // sendMessageOfTranslate(message: string) {
  //   const destLocale = this.destLocale;
  //   const original = StringUtil.escapeHtml(message);
  //   const roomSeq = this.roomInfoSubject.value.roomSeq;

  //   if (!!this.isTranslationProcess) {
  //     return;
  //   }

  //   this.isTranslationProcess = true;
  //   this.commonApiService
  //     .translationSave({
  //       userSeq: this.loginResSubject.value.userSeq,
  //       deviceType: this.environmentsInfo.deviceType,
  //       token: this.loginResSubject.value.tokenString,
  //       roomSeq,
  //       original,
  //       srcLocale: '',
  //       destLocale
  //     } as TranslationSaveRequest)
  //     .pipe(
  //       take(1),
  //       map(res => {
  //         if (res.statusCode === StatusCode.Success) {
  //           let sentMessage = '';
  //           let eventType = EventType.Translation;
  //           let previewObject: TranslationEventJson | MassTranslationEventJson;

  //           if (res.translationSeq > 0) {
  //             // Mass Text Translation
  //             previewObject = res;
  //             sentMessage = res.returnJson;
  //             eventType = EventType.MassTranslation;
  //           } else {
  //             // Normal Text Translation
  //             previewObject = {
  //               locale: destLocale,
  //               original,
  //               translation: res.translation,
  //               stickername: '',
  //               stickerfile: !!this.selectedSticker
  //                 ? this.selectedSticker.index
  //                 : ''
  //             };

  //             sentMessage = JSON.stringify(previewObject);
  //             eventType = EventType.Translation;
  //           }

  //           if (!!this.translationPreview) {
  //             // preview
  //             this.translationPreviewInfo = {
  //               previewInfo: res,
  //               translationType: eventType
  //             };
  //           } else {
  //             // direct send
  //             this.store.dispatch(
  //               EventStore.send({
  //                 senderSeq: this.loginResSubject.value.userSeq,
  //                 req: {
  //                   roomSeq,
  //                   eventType,
  //                   sentMessage
  //                 }
  //               })
  //             );

  //             if (!!this.translationPreviewInfo) {
  //               this.translationPreviewInfo = null;
  //             }
  //           }

  //           if (!!this.selectedSticker) {
  //             this.isShowStickerSelector = false;
  //             this.setStickerHistory(this.selectedSticker);
  //             this.selectedSticker = null;
  //           }
  //         } else {
  //           this.isTranslationProcess = false;
  //           this.dialogService.open<
  //             AlertDialogComponent,
  //             AlertDialogData,
  //             AlertDialogResult
  //           >(AlertDialogComponent, {
  //             width: '360px',
  //             data: {
  //               title: '',
  //               message: this.translateService.instant(
  //                 'chat.error.translateServerError'
  //               )
  //             }
  //           });
  //           this.logger.error('res', res);
  //         }
  //       }),
  //       catchError(error => {
  //         this.isTranslationProcess = false;
  //         this.dialogService.open<
  //           AlertDialogComponent,
  //           AlertDialogData,
  //           AlertDialogResult
  //         >(AlertDialogComponent, {
  //           width: '360px',
  //           data: {
  //             title: '',
  //             message: this.translateService.instant(
  //               'chat.error.translateServerError'
  //             )
  //           }
  //         });
  //         return of(this.logger.error('error', error));
  //       })
  //     )
  //     .subscribe(() => {
  //       this.isTranslationProcess = false;
  //     });
  // }

  onClickReceiveAlarm() {
    this.store.dispatch(
      RoomStore.updateOnlyAlarm({ roomInfo: this.roomInfoSubject.value })
    );
  }

  /** MassText Detail View */
  onMassDetail(value: number) {
    this.store.dispatch(
      ChatStore.selectedMassDetail({
        massEventSeq: value
      })
    );
  }

  onMassTranslationDetail(params: {
    message: Info<MassTranslationEventJson>;
    contentsType: string;
  }) {
    this.commonApiService
      .transMassTalkDownload({
        userSeq: this.loginResSubject.value.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginResSubject.value.tokenString,
        eventTransSeq: params.message.sentMessageJson.translationSeq.toString()
      })
      .pipe(take(1))
      .subscribe(res => {
        let contents = '';
        if (res.statusCode === StatusCode.Success) {
          contents =
            params.contentsType === 'T' ? res.translation : res.original;
        } else {
          contents =
            params.contentsType === 'T'
              ? params.message.sentMessageJson.translation
              : params.message.sentMessageJson.original;
        }

        this.dialogService.open<MassDetailComponent, MassDetailDialogData>(
          MassDetailComponent,
          {
            disableClose: false,
            width: '550px',
            data: {
              title: this.translateService.instant('chat.detailView'),
              contents
            }
          }
        );
      });
  }

  async onFileViewer(selectFileInfo: SelectFileInfo) {
    const result = await this.dialogService.open<
      FileViewerDialogComponent,
      FileViewerDialogData,
      FileViewerDialogResult
    >(FileViewerDialogComponent, {
      position: {
        top: '50px'
      },
      maxWidth: '100vw',
      maxHeight: '100vh',
      height: 'calc(100% - 50px)',
      width: '100%',
      hasBackdrop: false,
      panelClass: 'app-dialog-full',
      data: {
        fileInfos: this.fileInfoListSubject.value,
        selectFileInfo,
        downloadUrl: this.sessionVerInfo.downloadUrl,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginResSubject.value.tokenString,
        userSeq: this.loginResSubject.value.userSeq
      }
    });
  }

  /** File Save, Save As */
  onSave(value: {
    fileInfo: FileEventJson;
    fileDownloadItem: FileDownloadItem;
    type: string;
  }) {
    this.logger.debug('fileSave', value);
    if (value.type === 'saveAs') {
      this.nativeService
        .selectSaveFilePath(value.fileInfo.fileName)
        .then(result => {
          if (!result) {
            return;
          }

          if (result.canceled) {
            // this.snackBarService.open(
            //   this.translateService.instant('common.file.results.canceled'),
            //   this.translateService.instant('common.file.errors.label'),
            //   {
            //     duration: 1000
            //   }
            // );
          } else {
            this.saveFile(value, result.filePath);
          }
        })
        .catch(reason => {
          this.snackBarService.open(
            this.translateService.instant(
              'common.file.errors.failToSpecifyPath'
            ),
            this.translateService.instant('common.file.errors.label')
          );
        });
    } else {
      this.saveFile(value);
    }
  }

  onFileDragEnter(items: DataTransferItemList) {
    this.clearView();
    this.logger.debug('onFileDragEnter', items);
  }

  onFileDragOver() {
    this.logger.debug('onFileDragOver');
  }

  onFileDragLeave() {
    this.logger.debug('onFileDragLeave');
  }

  onExistNewMessage(info: Info<EventJson>) {
    let message = '';

    const contents = StringUtil.convertFinalEventMessage(
      info.type,
      info.sentMessageJson || info.sentMessage
    );

    if (!!contents) {
      const senderUser = this.userInfoListSubject.value.filter(
        user => user.seq === info.senderSeq
      );
      if (!!senderUser && senderUser.length > 0) {
        message += `${senderUser[0].name} : `;
      }
      message += contents;

      this.snackBarPreviewEvent = this.snackBarService.open(
        message,
        this.translateService.instant('common.messages.confirm'),
        {
          // duration: 3000,
          verticalPosition: 'bottom',
          horizontalPosition: 'center',
          panelClass: ['chat-snackbar-class']
        }
      );
      this.snackBarPreviewEvent.onAction().subscribe(() => {
        this.chatMessages.initEventMore();
        this.chatMessages.scrollToBottom();
        this.snackBarPreviewEvent.dismiss();
      });
    }
  }

  saveFile(
    value: {
      fileInfo: FileEventJson;
      fileDownloadItem: FileDownloadItem;
      type: string;
    },
    savePath?: string
  ) {
    this.appFileService.fileTalkDownlod({
      req: {
        userSeq: this.loginResSubject.value.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginResSubject.value.tokenString,
        attachmentsSeq: value.fileInfo.attachmentSeq,
        fileDownloadItem: value.fileDownloadItem
      },
      fileName: value.fileInfo.fileName,
      savePath
    });
  }

  async onFileSelected(fileUploadItems: FileUploadItem[]) {
    this.logger.debug('onFileSelected', fileUploadItems);
    this.clearView();

    const fileAllowSize =
      !!this.sessionVerInfo && this.sessionVerInfo.fileAllowSize
        ? this.sessionVerInfo.fileAllowSize
        : environment.productConfig.CommonSetting.defaultFileAllowSize;

    if (fileAllowSize > 0) {
      if (
        fileUploadItems.filter(
          fui => fui.file.size > fileAllowSize * 1024 * 1024
        ).length
      ) {
        this.snackBarService.open(
          this.translateService.instant('common.file.errors.oversize', {
            maxSize: fileAllowSize
          }),
          '',
          {
            duration: 1000,
            verticalPosition: 'bottom',
            horizontalPosition: 'center'
          }
        );

        if (!!this.fileUploadQueue) {
          this.fileUploadQueue.onUploadComplete();
        }
        return;
      }
    }

    const checkExt = this.commonApiService.acceptableExtensionForFileTalk(
      fileUploadItems.map(fui => FileUtil.getExtension(fui.file.name))
    );
    if (!checkExt.accept) {
      if (!!this.fileUploadQueue) {
        this.fileUploadQueue.onUploadComplete();
      }

      this.snackBarService.open(
        this.translateService.instant('common.file.errors.notSupporedType', {
          supporedType:
            checkExt.reject.length > 0 ? checkExt.reject.join(',') : ''
        }),
        '',
        {
          duration: 1000,
          verticalPosition: 'bottom',
          horizontalPosition: 'center'
        }
      );

      return;
    }

    this.isImageOnlyForFileUpload = this.isImageOnly(fileUploadItems);

    if (this.isImageOnlyForFileUpload) {
      this.bundleFileUploadItem = FileUploadItem.from();
      this.bundleFileUploadItems = fileUploadItems;
      return;
    }
    this.bundleFileUploadItem = undefined;
    this.bundleFileUploadItems = undefined;

    await this.uploadFiles(fileUploadItems);
  }

  private uploadFiles(fileUploadItems: FileUploadItem[]): Promise<void> {
    // 일반 업로드
    return new Promise<void>(async (resolve, reject) => {
      const allObservables: Observable<FileTalkSaveResponse>[] = [];

      for (const fileUploadItem of fileUploadItems) {
        let thumbnail: File;
        if (
          -1 !==
          [
            '3gp',
            'avi',
            'm4v',
            'mkv',
            'mov',
            'mp4',
            'mpeg',
            'mpg',
            'rv',
            'ts',
            'webm',
            'wmv'
          ].indexOf(FileUtil.getExtension(fileUploadItem.file.name))
        ) {
          thumbnail = await FileUtil.thumbnail(fileUploadItem.file);
          this.logger.debug('thumbnail', thumbnail);
        }

        const req: FileTalkSaveRequest = {
          userSeq: this.loginResSubject.value.userSeq,
          deviceType: this.environmentsInfo.deviceType,
          token: this.loginResSubject.value.tokenString,
          roomSeq: this.roomInfoSubject.value.roomSeq,
          file: fileUploadItem.file,
          fileName: fileUploadItem.file.name,
          thumb: thumbnail,
          fileUploadItem
        };

        allObservables.push(
          this.commonApiService.fileTalkSave(req, null).pipe(
            map(res => {
              if (!res) {
                return;
              }
              if (StatusCode.Success === res.statusCode) {
                return res;
              } else {
                throw res;
              }
            })
          )
        );
      }

      const info = {
        senderSeq: this.loginResSubject.value.userSeq,
        roomSeq: this.roomInfoSubject.value.roomSeq
      };

      forkJoin(allObservables)
        .pipe(take(1))
        .subscribe(
          resList => {
            for (const res of resList) {
              this.store.dispatch(
                EventStore.send({
                  senderSeq: info.senderSeq,
                  req: {
                    roomSeq: info.roomSeq,
                    eventType: EventType.File,
                    sentMessage: res.returnJson
                  }
                })
              );
            }
            resolve();
          },
          error => {
            this.logger.debug('onFileSelected error', error);
            this.snackBarService.open(
              this.translateService.instant('common.file.errors.failToUpload'),
              this.translateService.instant('common.file.errors.label')
            );

            if (!!this.fileUploadQueue) {
              this.fileUploadQueue.onUploadComplete();
            }
            reject(error);
          },
          () => {
            this.fileUploadQueue.onUploadComplete();
          }
        );
    });
  }

  private uploadBundleFile(): Promise<void> {
    return new Promise<void>((resolve, reject) => {
      const fileList: File[] = [];
      const info = {
        senderSeq: this.loginResSubject.value.userSeq,
        roomSeq: this.roomInfoSubject.value.roomSeq
      };
      for (const fileUploadItem of this.bundleFileUploadItems) {
        fileList.push(fileUploadItem.file);
      }
      const req: FileTalkSaveMultiRequest = {
        userSeq: this.loginResSubject.value.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginResSubject.value.tokenString,
        roomSeq: this.roomInfoSubject.value.roomSeq,
        fileUploadItem: this.bundleFileUploadItem,
        files: fileList
      };

      this.commonApiService
        .fileTalkSaveMulti(req, null)
        .pipe(
          map(res => {
            if (!res) {
              return;
            }
            if (StatusCode.Success === res.statusCode) {
              return res;
            } else {
              throw res;
            }
          })
        )
        .subscribe(
          res => {
            this.logger.debug('fileTalkSaveMulti', res);

            this.store.dispatch(
              EventStore.send({
                senderSeq: info.senderSeq,
                req: {
                  roomSeq: info.roomSeq,
                  eventType: EventType.BundleImage,
                  sentMessage: res.returnJson
                }
              })
            );
            resolve();
          },
          error => {
            this.logger.debug('onFileSelected error', error);
            this.snackBarService.open(
              this.translateService.instant('common.file.errors.failToUpload'),
              this.translateService.instant('common.file.errors.label')
            );

            if (!!this.fileUploadQueue) {
              this.fileUploadQueue.onUploadComplete();
            }
            reject(error);
          },
          () => {
            this.bundleFileUploadItem = undefined;
            this.bundleFileUploadItems = undefined;

            this.fileUploadQueue.onUploadComplete();
          }
        );
    });
  }

  private isImageOnly(fileUploadItems: FileUploadItem[]): boolean {
    if (!fileUploadItems || 0 === fileUploadItems.length) {
      return false;
    }

    for (const fileUploadItem of fileUploadItems) {
      if (-1 === fileUploadItem.file.type.indexOf('image/')) {
        return false;
      }
    }
    return true;
  }

  onContextMenuMessage(params: {
    event: MouseEvent;
    message: Info<EventJson>;
    type?: string;
  }) {
    params.event.preventDefault();
    params.event.stopPropagation();

    this.messageContextMenuPosition.x = params.event.clientX + 'px';
    this.messageContextMenuPosition.y = params.event.clientY + 'px';
    this.messageContextMenuTrigger.menu.focusFirstItem('mouse');
    this.messageContextMenuTrigger.menuData = {
      message: params.message,
      loginRes: this.loginResSubject.value,
      clicktype: params.type
    };
    this.messageContextMenuTrigger.openMenu();
  }

  async onClickMessageContextMenu(
    menuType: string,
    message: Info<EventJson>,
    clicktype?: string
  ) {
    switch (menuType) {
      case 'COPY':
        {
          switch (message.type) {
            case EventType.Character:
              {
                if (
                  this.clipboardService.copyFromContent(
                    (message as Info<string>).sentMessage
                  )
                ) {
                  this.snackBarService.open(
                    this.translateService.instant(
                      'common.clipboard.results.copied'
                    ),
                    '',
                    {
                      duration: 3000,
                      verticalPosition: 'top',
                      horizontalPosition: 'center'
                    }
                  );
                }
              }
              break;
            case EventType.MassText:
              {
                this.commonApiService
                  .massTalkDownload({
                    userSeq: this.loginResSubject.value.userSeq,
                    deviceType: this.environmentsInfo.deviceType,
                    token: this.loginResSubject.value.tokenString,
                    eventMassSeq: message.seq
                  })
                  .pipe(take(1))
                  .subscribe(res => {
                    if (this.clipboardService.copyFromContent(res.content)) {
                      this.snackBarService.open(
                        this.translateService.instant(
                          'common.clipboard.results.copied'
                        ),
                        '',
                        {
                          duration: 3000,
                          verticalPosition: 'top',
                          horizontalPosition: 'center'
                        }
                      );
                    }
                  });
              }
              break;
            case EventType.Translation:
              {
                let trgtStr = '';
                if (clicktype === 'translation') {
                  // translation
                  trgtStr = (message.sentMessageJson as TranslationEventJson)
                    .translation;
                } else {
                  // original
                  trgtStr = (message.sentMessageJson as TranslationEventJson)
                    .original;
                }

                if (this.clipboardService.copyFromContent(trgtStr)) {
                  this.snackBarService.open(
                    this.translateService.instant(
                      'common.clipboard.results.copied'
                    ),
                    '',
                    {
                      duration: 3000,
                      verticalPosition: 'top',
                      horizontalPosition: 'center'
                    }
                  );
                }
              }
              break;
            case EventType.MassTranslation:
              {
                const sentMessageJson: MassTranslationEventJson = message.sentMessageJson as MassTranslationEventJson;
                this.commonApiService
                  .transMassTalkDownload({
                    userSeq: this.loginResSubject.value.userSeq,
                    deviceType: this.environmentsInfo.deviceType,
                    token: this.loginResSubject.value.tokenString,
                    eventTransSeq: sentMessageJson.translationSeq.toString()
                  })
                  .pipe(take(1))
                  .subscribe(res => {
                    let contents = '';
                    if (res.statusCode === StatusCode.Success) {
                      contents =
                        clicktype === 'translation'
                          ? res.translation
                          : res.original;
                    } else {
                      contents =
                        clicktype === 'translation'
                          ? sentMessageJson.translation
                          : sentMessageJson.original;
                    }

                    if (this.clipboardService.copyFromContent(contents)) {
                      this.snackBarService.open(
                        this.translateService.instant(
                          'common.clipboard.results.copied'
                        ),
                        '',
                        {
                          duration: 3000,
                          verticalPosition: 'top',
                          horizontalPosition: 'center'
                        }
                      );
                    }
                  });
              }
              break;
            default:
              break;
          }
        }
        break;
      case 'FORWARD':
        {
          const result = await this.dialogService.open<
            CreateChatDialogComponent,
            CreateChatDialogData,
            CreateChatDialogResult
          >(CreateChatDialogComponent, {
            width: '600px',
            data: {
              type: UserSelectDialogType.MessageForward,
              title: this.translateService.instant('chat.forwardEventTo'),
              ignoreRoom: [this.roomInfoSubject.value]
            }
          });

          if (!!result && !!result.choice && result.choice) {
            const userSeqs: number[] = [];
            let roomSeq = '';
            if (
              !!result.selectedUserList &&
              result.selectedUserList.length > 0
            ) {
              result.selectedUserList.map(user => userSeqs.push(user.seq));
            }

            if (!!result.selectedRoom) {
              roomSeq = result.selectedRoom.roomSeq;
            }

            if (userSeqs.length > 0 || roomSeq.trim().length > 0) {
              this.store.dispatch(
                EventStore.forward({
                  senderSeq: this.loginResSubject.value.userSeq,
                  req: {
                    roomSeq: '-999',
                    eventType: message.type,
                    sentMessage: message.sentMessage
                  },
                  trgtUserSeqs: userSeqs,
                  trgtRoomSeq: roomSeq
                })
              );
            }
          }
        }
        break;
      case 'FORWARD_TO_ME':
        {
          if (this.loginResSubject.value.talkWithMeBotSeq > -1) {
            this.store.dispatch(
              EventStore.forward({
                senderSeq: this.loginResSubject.value.userSeq,
                req: {
                  roomSeq: '-999',
                  eventType: message.type,
                  sentMessage: message.sentMessage
                },
                trgtUserSeqs: [this.loginResSubject.value.talkWithMeBotSeq]
              })
            );
          }
        }
        break;
      case 'DELETE':
        {
          const result = await this.dialogService.open<
            ConfirmDialogComponent,
            ConfirmDialogData,
            ConfirmDialogResult
          >(ConfirmDialogComponent, {
            width: '400px',
            data: {
              title: this.translateService.instant('chat.removeEvent'),
              html: this.translateService.instant('chat.confirmRemoveEvent')
            }
          });

          if (!!result && !!result.choice && result.choice) {
            this.store.dispatch(
              EventStore.del({
                roomSeq: this.roomInfoSubject.value.roomSeq,
                eventSeq: message.seq
              })
            );
          }
        }
        break;
      case 'RECALL':
        {
          const result = await this.dialogService.open<
            ConfirmDialogComponent,
            ConfirmDialogData,
            ConfirmDialogResult
          >(ConfirmDialogComponent, {
            width: '400px',
            data: {
              title: this.translateService.instant('chat.recallEvent'),
              html: this.translateService.instant('chat.confirmRecallEvent')
            }
          });

          if (!!result && !!result.choice && result.choice) {
            this.store.dispatch(
              EventStore.cancel({
                roomSeq: this.roomInfoSubject.value.roomSeq,
                eventSeq: message.seq,
                deviceType: this.environmentsInfo.deviceType
              })
            );
          }
        }
        break;
      default:
        break;
    }
  }

  async onClickContextMenu(menuType: string) {
    switch (menuType) {
      case 'OPEN_ALBUM_LIST':
        {
          this.store.dispatch(
            ChatStore.selectedRightDrawer({
              req: RightDrawer.AlbumBox
            })
          );
        }
        break;
      case 'OPEN_FILE_LIST':
        {
          this.store.dispatch(
            ChatStore.selectedRightDrawer({
              req: RightDrawer.FileBox
            })
          );
        }
        break;
      case 'CHAT_SEARCH':
        {
          this.onShowToggleSearchArea();
        }
        break;
      case 'OPEN_ROOM_USER':
        {
          this.store.dispatch(
            ChatStore.selectedRightDrawer({
              req: RightDrawer.RoomUser
            })
          );
        }
        break;
      case 'ADD_MEMBER':
        {
          const curRoomUser = this.userInfoListSubject.value.filter(
            user =>
              user.seq !== this.loginResSubject.value.userSeq && user.isJoinRoom
          );

          const result = await this.dialogService.open<
            CreateChatDialogComponent,
            CreateChatDialogData,
            CreateChatDialogResult
          >(CreateChatDialogComponent, {
            width: '600px',
            data: {
              type: UserSelectDialogType.EditChatMember,
              title: this.translateService.instant('chat.modifyRoomMember'),
              curRoomUser
            }
          });

          if (!!result && !!result.choice && result.choice) {
            if (
              !!result.selectedUserList &&
              result.selectedUserList.length > 0 &&
              curRoomUser
                .map(user => user.seq)
                .sort()
                .join('|') ===
                result.selectedUserList
                  .map(user => user.seq)
                  .sort()
                  .join('|')
            ) {
              // 변경된 것이 없다면 중지.
              return;
            }

            // include me here..
            const userSeqs: number[] = this.userInfoListSubject.value
              .filter(userInfo => userInfo.isJoinRoom)
              .map(userInfo => userInfo.seq);

            if (
              !!result.selectedUserList &&
              result.selectedUserList.length > 0
            ) {
              result.selectedUserList.forEach(user => {
                if (userSeqs.indexOf(user.seq) < 0) {
                  userSeqs.push(user.seq);
                }
              });
            }

            if (userSeqs.length > 0) {
              // include me
              const myUserSeq = this.loginResSubject.value.userSeq;
              if (!!myUserSeq && userSeqs.indexOf(myUserSeq) < 0) {
                userSeqs.push(myUserSeq);
              }

              this.store.dispatch(
                RoomStore.inviteOrOpen({
                  req: {
                    divCd: 'Invite',
                    userSeqs
                  }
                })
              );
            }
          }
        }
        break;
      case 'ADD_GROUP':
        {
          const result = await this.dialogService.open<
            SelectGroupDialogComponent,
            SelectGroupDialogData,
            SelectGroupDialogResult
          >(SelectGroupDialogComponent, {
            width: '600px',
            data: {
              title: this.translateService.instant('chat.addMemberToGroup')
            }
          });

          if (!!result && !!result.choice && result.choice) {
            if (!!result.group) {
              const oldGroup: GroupDetailData = result.group;
              const trgtUserSeq: number[] = [];
              result.group.userSeqs.map(seq => trgtUserSeq.push(seq));
              this.userInfoListSubject.value
                .filter(v => v.isJoinRoom)
                .filter(v => result.group.userSeqs.indexOf(v.seq) < 0)
                .forEach(user => {
                  trgtUserSeq.push(user.seq);
                });

              this.store.dispatch(
                SyncStore.updateGroupMember({
                  oldGroup,
                  trgtUserSeq
                })
              );
            }
          }
        }
        break;
      case 'EDIT_ROOM':
        {
          const result = await this.dialogService.open<
            EditChatRoomDialogComponent,
            EditChatRoomDialogData,
            EditChatRoomDialogResult
          >(EditChatRoomDialogComponent, {
            width: '600px',
            data: {
              title: this.translateService.instant('chat.settingsOfRoom'),
              roomInfo: this.roomInfoSubject.value
            }
          });

          if (!!result && !!result.choice && result.choice) {
            const roomName: string = result.roomName;
            const roomNameChangeTarget: string = result.roomNameChangeTarget;
            const timeRoomInterval: number = result.timeRoomInterval;
            const roomInfo: RoomInfo = result.roomInfo;

            // 방제목 업데이트.
            this.store.dispatch(
              RoomStore.update({
                req: {
                  roomSeq: roomInfo.roomSeq,
                  roomName,
                  receiveAlarm: roomInfo.receiveAlarm,
                  syncAll:
                    roomNameChangeTarget.toUpperCase() === 'ALL' ? true : false
                }
              })
            );

            if (
              roomInfo.isTimeRoom &&
              timeRoomInterval > 0 &&
              roomInfo.timeRoomInterval !== timeRoomInterval
            ) {
              this.store.dispatch(
                RoomStore.updateTimeRoomInterval({
                  roomSeq: roomInfo.roomSeq,
                  timerInterval: timeRoomInterval
                })
              );
            }
          }
        }
        break;
      case 'CLOSE_ROOM':
        {
          this.store.dispatch(ChatStore.clearSelectedRoom());
        }
        break;
      default:
        break;
    }
  }

  onClickOpenProfile(userSeq: number) {
    const roomType = this.roomInfoSubject.value.roomType;
    if (
      roomType !== RoomType.Allim &&
      roomType !== RoomType.Bot &&
      roomType !== RoomType.Link &&
      roomType !== RoomType.Allim_Elephant &&
      roomType !== RoomType.Allim_TMS
    ) {
      this.openProfile.emit({ userSeq });
    }
  }

  /** About Sticker */
  onShowToggleStickerSelector() {
    this.isShowStickerSelector = !this.isShowStickerSelector;
    if (!this.isShowStickerSelector) {
      this.selectedSticker = null;
    }
  }
  onSelectedSticker(stickerInfo: StickerFilesInfo) {
    this.selectedSticker = stickerInfo;
  }
  setStickerHistory(sticker: StickerFilesInfo) {
    const history = this.localStorageService.get<string[]>(KEY_STICKER_HISTORY);

    if (!!history && history.length > 0) {
      const stickers: string[] = [];
      [sticker.index, ...history.filter(hist => hist !== sticker.index)].map(
        (s, i) => {
          if (i < 10) {
            stickers.push(s);
          }
        }
      );

      this.localStorageService.set<string[]>(KEY_STICKER_HISTORY, stickers);
    } else {
      this.localStorageService.set<string[]>(KEY_STICKER_HISTORY, [
        sticker.index
      ]);
    }
  }
  getStickerHistory(): string[] {
    return this.localStorageService.get<string[]>(KEY_STICKER_HISTORY);
  }

  /** About Chat Search */
  onShowToggleSearchArea() {
    this.isShowSearchArea = !this.isShowSearchArea;

    if (!this.isShowSearchArea) {
      this.searchedListSubject.next([]);
      this.searchedFocusEvent = null;
      this.searchText = '';
    }
  }
  onCloseSearchArea() {
    this.isShowSearchArea = false;
    this.searchedListSubject.next([]);
    this.searchedFocusEvent = null;
    this.searchText = '';

    this.moreSearchProcessing = false;
    this.searchTotalCount = 0;
    this.searchCurrentIndex = 0;

    this.store.dispatch(EventStore.infoForSearchEnd({}));
  }
  onSearchChat(searchText: string, baseSeq?: number) {
    this.searchText = searchText;

    // CASE :: searching text after retrieve All event Infos.
    this.store.dispatch(
      EventStore.infoAll({
        req: {
          roomSeq: this.roomInfoSubject.value.roomSeq,
          baseSeq: this.eventListSubject.value[0].seq,
          requestCount:
            environment.productConfig.CommonSetting.eventRequestDefaultCount * 2
        },
        infoList: undefined
      })
    );

    // this.doSearchTextInEvent(searchText);
  }
  doSearchTextInEvent(searchText: string, baseSeq?: number): void {
    this.searchedListSubject.next(
      this.eventListSubject.value.filter(event => {
        let contents = '';
        if (event.type === EventType.Character) {
          contents = event.sentMessage;
        } else if (
          event.type === EventType.Sticker &&
          !!event.sentMessageJson
        ) {
          contents = (event.sentMessageJson as StickerEventJson).chat;
        } else if (event.type === EventType.File && !!event.sentMessageJson) {
          contents = (event.sentMessageJson as FileEventJson).fileName;
        } else if (
          event.type === EventType.MassText &&
          !!event.sentMessageJson
        ) {
          contents = (event.sentMessageJson as MassTextEventJson).content;
        } else if (
          (event.type === EventType.Translation ||
            event.type === EventType.MassTranslation) &&
          !!event.sentMessageJson
        ) {
          contents = (event.sentMessageJson as TranslationEventJson).original;
          contents += (event.sentMessageJson as TranslationEventJson)
            .translation;
        }

        return contents.indexOf(searchText) > -1;
      })
    );

    if (
      !!this.searchedListSubject.value &&
      this.searchedListSubject.value.length > 0
    ) {
      this.searchTotalCount = this.searchedListSubject.value.length;

      if (!!baseSeq && baseSeq > 0) {
        this.searchedListSubject.value.forEach((searched, index) => {
          if (searched.seq <= baseSeq) {
            this.searchCurrentIndex = index + 1;
            this.searchedFocusEvent = searched;
          }
        });
      } else {
        this.searchCurrentIndex = this.searchedListSubject.value.length;
        this.searchedFocusEvent = this.searchedListSubject.value[
          this.searchedListSubject.value.length - 1
        ];
      }

      this.store.dispatch(EventStore.infoForSearchEnd({}));

      // this.chatMessages.gotoPosition(this.searchedFocusEvent.seq);
      this.chatMessages.initEventMore(this.searchedFocusEvent.seq);
    } else {
      this.searchTotalCount = 0;
      this.searchCurrentIndex = 0;

      this.searchedFocusEvent = null;
    }
  }
  onPrevSearch() {
    this.searchedListSubject.value.forEach((event, index) => {
      if (event.seq === this.searchedFocusEvent.seq && index > 0) {
        this.searchCurrentIndex = this.searchCurrentIndex - 1;
        this.searchedFocusEvent = this.searchedListSubject.value[index - 1];
        this.chatMessages.gotoPosition(this.searchedFocusEvent.seq);
      }
    });
  }
  onNextSearch() {
    // let exist = false;
    // this.searchedList.forEach((event, index) => {
    //   if (
    //     event.seq === this.searchedFocusEvent.seq &&
    //     index < this.searchedList.length - 2 &&
    //     !exist
    //   ) {
    //     exist = true;
    //     this.searchCurrentIndex = this.searchCurrentIndex + 1;
    //     this.searchedFocusEvent = this.searchedList[index + 1];
    //     this.goSearchPosition(this.searchedFocusEvent.seq);
    //   }
    // });

    if (this.searchCurrentIndex < this.searchedListSubject.value.length) {
      this.searchedFocusEvent = this.searchedListSubject.value[
        this.searchCurrentIndex
      ];
      this.searchCurrentIndex = this.searchCurrentIndex + 1;
      this.chatMessages.gotoPosition(this.searchedFocusEvent.seq);
    }
  }
  onSearchAndPrev() {
    if (
      !!this.searchText &&
      this.searchText.trim().length > 0 &&
      this.eventRemainedSubject.value
    ) {
      this.moreSearchProcessing = true;
      this.chatMessages.storeScrollPosition();

      // Case :: retrieve event infos step by step until include searchtext in event..
      this.store.dispatch(
        EventStore.infoForSearch({
          req: {
            roomSeq: this.roomInfoSubject.value.roomSeq,
            baseSeq: this.eventListSubject.value[0].seq,
            requestCount:
              environment.productConfig.CommonSetting.eventRequestDefaultCount
          },
          searchText: this.searchText
        })
      );
    }
  }

  /**
   * 번역기능 비활성화 2020-02-07
   * About Translation */
  // onShowToggleTranslation() {
  //   this.isShowTranslation = !this.isShowTranslation;
  //   if (!this.isShowTranslation) {
  //   }
  // }
  // onChangeTranslationSimpleView(value: boolean) {
  //   this.translationSimpleview = value;
  // }
  // onChangeTranslationPreView(value: boolean) {
  //   this.translationPreview = value;
  // }
  // onChangeDestLocale(destLocale: string) {
  //   this.destLocale = destLocale;
  // }
  // onCancelTranslation() {
  //   this.isTranslationProcess = false;
  //   this.translationPreviewInfo = null;
  // }

  // onSendTranslationMessage(params: {
  //   previewInfo: TranslationSaveResponse | null;
  //   translationType: EventType.Translation | EventType.MassTranslation;
  // }) {
  //   let sentMessage = '';
  //   if (params.translationType === EventType.MassTranslation) {
  //     // Mass Text Translation
  //     sentMessage = params.previewInfo.returnJson;
  //   } else {
  //     // Normal Text Translation
  //     sentMessage = JSON.stringify({
  //       locale: params.previewInfo.destLocale,
  //       original: params.previewInfo.original,
  //       translation: params.previewInfo.translation,
  //       stickername: '',
  //       stickerfile: !!this.selectedSticker ? this.selectedSticker.index : ''
  //     });
  //   }

  //   this.store.dispatch(
  //     EventStore.send({
  //       senderSeq: this.loginResSubject.value.userSeq,
  //       req: {
  //         roomSeq: this.roomInfoSubject.value.roomSeq,
  //         eventType: params.translationType,
  //         sentMessage
  //       }
  //     })
  //   );

  //   this.isTranslationProcess = false;
  //   this.translationPreviewInfo = null;
  // }

  onClipboardPaste(event: ClipboardEvent) {
    this.nativeService.readFromClipboard().then(async data => {
      if (!!data.image && !!data.text) {
        const result = await this.dialogService.open<
          ClipboardDialogComponent,
          ClipboardDialogData,
          ClipboardDialogResult
        >(ClipboardDialogComponent, {
          width: '800px',
          maxWidth: '800px',
          height: '800px',
          minHeight: '800px',
          disableClose: false,
          data: {
            content: data
          }
        });

        if (result.selected.text) {
          this.onSendMessage(data.text.replace(/\t/g, '    '));
        }

        if (result.selected.image) {
          const fileUploadItems = FileUploadItem.fromDataUrls(
            'clipboard',
            data.imageDataUrl
          );

          this.onFileSelected(fileUploadItems);
        }
      } else if (!!data.image && !data.text) {
        const fileUploadItems = FileUploadItem.fromDataUrls(
          'clipboard',
          data.imageDataUrl
        );

        this.onFileSelected(fileUploadItems);
      } else {
        const v = this.chatForm.replyInput.nativeElement.value;
        const selectionStart = this.chatForm.replyInput.nativeElement
          .selectionStart;
        const selectionEnd = this.chatForm.replyInput.nativeElement
          .selectionEnd;

        const start = v.substr(0, selectionStart);
        const end = v.substr(selectionEnd);

        this.chatForm.replyInput.nativeElement.value = `${start}${data.text}${end}`;

        event.preventDefault();
      }
    });
  }
}
