import {
  Component,
  OnInit,
  OnDestroy,
  ViewChild,
  AfterViewInit,
  Output,
  EventEmitter,
  Inject
} from '@angular/core';
import {
  ucapAnimations,
  SnackBarService,
  ClipboardService,
  DialogService,
  ConfirmDialogComponent,
  ConfirmDialogData,
  ConfirmDialogResult,
  AlertDialogComponent,
  AlertDialogData,
  AlertDialogResult,
  FileUploadQueueComponent,
  StringUtil,
  AlertSnackbarComponent,
  AlertSnackbarData
} from '@ucap-webmessenger/ui';
import { Store, select } from '@ngrx/store';
import { NGXLogger } from 'ngx-logger';
import { Observable, Subscription, forkJoin, combineLatest, of } 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 } from '@ucap-webmessenger/protocol-room';
import { tap, take, map, catchError, finalize } from 'rxjs/operators';
import { FormComponent as UCapUiChatFormComponent } from '@ucap-webmessenger/ui-chat';
import { KEY_VER_INFO } from '@app/types';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import {
  MatMenuTrigger,
  MatSnackBarRef,
  SimpleSnackBar
} from '@angular/material';
import { FileUploadItem, FileDownloadItem } from '@ucap-webmessenger/api';
import {
  CommonApiService,
  FileTalkSaveRequest,
  FileTalkSaveResponse,
  TranslationSaveRequest,
  TranslationSaveResponse
} 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, MimeUtil } from '@ucap-webmessenger/core';
import { PerfectScrollbarComponent } from 'ngx-perfect-scrollbar';
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';

@Component({
  selector: 'app-layout-messenger-messages',
  templateUrl: './messages.component.html',
  styleUrls: ['./messages.component.scss'],
  animations: ucapAnimations
})
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('psChatContent', { static: true })
  psChatContent: PerfectScrollbarComponent;

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

  environmentsInfo: EnvironmentsInfo;

  loginRes: LoginResponse;
  loginResSubscription: Subscription;
  eventList: Info<EventJson>[];
  eventListNew: Info<EventJson>[];
  eventListSubscription: Subscription;
  baseEventSeq = 0;
  roomInfo: RoomInfo;
  roomInfoSubscription: Subscription;
  userInfoList: UserInfo[];
  userInfoListSubscription: Subscription;
  eventListProcessing$: Observable<boolean>;
  searchEventListProcessing: boolean;
  searchEventListProcessingSubscription: Subscription;
  eventInfoStatus: InfoResponse;
  eventInfoStatusSubscription: Subscription;
  sessionVerInfo: VersionInfo2Response;

  eventRemain$: Observable<boolean>;
  eventRemain = false; // 이전대화가 남아 있는지 여부
  eventMorePosition = 0; // 이전대화를 불러올 경우 현재 스크롤 포지션 유지를 위한 값. 0 이면 초기로딩.
  scrollUpinit = false; // ps 에서 초기 로딩시 scroll reach start 이벤트 발생 버그를 우회하기 위한 init 값으로 scrollUp 에 의해 true 로 된다.

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

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

  /** About Searching */
  isShowSearchArea = false;
  moreSearchProcessing = false;
  searchText = '';
  searchedList: Info<EventJson>[];
  searchedFocusEvent: Info<EventJson>;
  searchTotalCount = 0;
  searchCurrentIndex = 0;

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

  /** 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;

  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 translateService: TranslateService,
    private dialogService: DialogService,
    private snackBarService: SnackBarService,
    @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
    private logger: NGXLogger
  ) {
    this.sessionVerInfo = this.sessionStorageService.get<VersionInfo2Response>(
      KEY_VER_INFO
    );

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

  setEventMoreInit() {
    // 방정보가 바뀌면 이전대화 보기 관련 값들을 초기화 한다.
    this.scrollUpinit = false;
    this.eventMorePosition = 0;
  }

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

    this.roomInfoSubscription = this.store
      .pipe(
        select(AppStore.MessengerSelector.RoomSelector.roomInfo),
        tap(roomInfo => {
          this.roomInfo = roomInfo;
          this.clearView();
          this.setEventMoreInit();
        })
      )
      .subscribe();

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

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

    this.searchEventListProcessingSubscription = this.store
      .pipe(
        select(
          AppStore.MessengerSelector.EventSelector.infoSearchListProcessing
        ),
        tap(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'
              }
            );
          }
        })
      )
      .subscribe();

    this.eventRemain$ = this.store.pipe(
      select(AppStore.MessengerSelector.EventSelector.remainInfo),
      tap(remainInfo => {
        this.eventRemain = remainInfo;
      })
    );

    // [Daesang]
    this.eventListSubscription = combineLatest([
      this.store.pipe(
        select(AppStore.MessengerSelector.EventSelector.selectAllInfoList)
      ),
      this.store.pipe(select(AppStore.MessengerSelector.RoomSelector.roomInfo))
    ])
      .pipe(
        tap(([infoList, roomInfo]) => {
          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;
            });

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

          this.eventList = 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;
              this.readyToReply();
            }
          }
        })
      )
      .subscribe();

    // // [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),
        tap(res => {
          this.eventInfoStatus = res;

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

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

  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.searchEventListProcessingSubscription) {
      this.searchEventListProcessingSubscription.unsubscribe();
    }

    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();

    // 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.replyForm.reset();
    }
  }

  get _roomUserInfos() {
    return this.userInfoList
      .filter(roomUserInfo => {
        return (
          this.loginRes.userSeq !== roomUserInfo.seq && roomUserInfo.isJoinRoom
        );
      })
      .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
  }

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

    if (
      this.roomInfo.roomType === RoomType.Bot ||
      this.roomInfo.roomType === RoomType.Allim ||
      this.roomInfo.roomType === RoomType.Link ||
      this.roomInfo.roomType === RoomType.Allim_Elephant ||
      this.roomInfo.roomType === RoomType.Allim_TMS
    ) {
      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 (
      menuType === 'OPEN_ROOM_USER' ||
      menuType === 'ADD_MEMBER' ||
      menuType === 'ADD_GROUP' ||
      menuType === 'EDIT_ROOM'
    ) {
      if (
        !this.roomInfo ||
        !this.roomInfo.roomType ||
        this.roomInfo.roomType === RoomType.Mytalk ||
        this.roomInfo.roomType === RoomType.Allim ||
        this.roomInfo.roomType === RoomType.Bot ||
        this.roomInfo.roomType === RoomType.Link ||
        this.roomInfo.roomType === RoomType.Allim_Elephant ||
        this.roomInfo.roomType === RoomType.Allim_TMS
      ) {
        return false;
      }
    }

    return true;
  }

  getShowUnreadCount(): boolean {
    if (!this.roomInfo || this.roomInfo === undefined) {
      return true;
    }
    if (
      this.roomInfo.roomType === RoomType.Mytalk ||
      this.roomInfo.roomType === RoomType.Allim ||
      this.roomInfo.roomType === RoomType.Bot ||
      this.roomInfo.roomType === RoomType.Link ||
      this.roomInfo.roomType === RoomType.Allim_Elephant ||
      this.roomInfo.roomType === RoomType.Allim_TMS
    ) {
      return false;
    }

    return true;
  }

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

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

  /** Scroll Handler */
  scrollToBottom(speed?: number): void {
    if (this.eventMorePosition > 0) {
      if (this.psChatContent.directiveRef) {
        this.psChatContent.directiveRef.update();

        const element = document.getElementById('message-box-readhere');
        if (!!element && this.firstcheckReadHere) {
          setTimeout(() => {
            this.psChatContent.directiveRef.scrollToTop(
              element.offsetTop - 200,
              speed
            );
          });

          this.firstcheckReadHere = false;
        } else {
          setTimeout(() => {
            this.psChatContent.directiveRef.scrollToTop(
              this.psChatContent.directiveRef.elementRef.nativeElement
                .scrollHeight - this.eventMorePosition,
              speed
            );

            this.eventMorePosition = 0;
          });
        }
      }
    } else if (this.scrollUpinit) {
      if (!!this.eventListNew && this.eventListNew.length > 0) {
        let message = '';
        const info = this.eventListNew[this.eventListNew.length - 1];
        const senderUser = this.userInfoList.filter(
          user => user.seq === info.senderSeq
        );
        if (!!senderUser && senderUser.length > 0) {
          message += `${senderUser[0].name} : `;
        }
        message += StringUtil.convertFinalEventMessage(
          info.type,
          info.sentMessageJson || info.sentMessage
        );

        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.setEventMoreInit();
          this.scrollToBottom();
          this.snackBarPreviewEvent.dismiss();
        });
      }
    } else {
      speed = speed || 0;
      if (this.psChatContent.directiveRef) {
        this.psChatContent.directiveRef.update();

        const element = document.getElementById('message-box-readhere');
        if (!!element && this.firstcheckReadHere) {
          setTimeout(() => {
            this.psChatContent.directiveRef.scrollToTop(
              element.offsetTop - 200,
              speed
            );
          });

          this.firstcheckReadHere = false;
        } else {
          setTimeout(() => {
            this.psChatContent.directiveRef.scrollToBottom(0, speed);
          });
        }
      }
    }
  }
  onScrollup(event: any) {
    this.scrollUpinit = true;
  }
  onScrollReachStart(event: any) {
    // 자동 스크롤이 아닌 버튼 방식으로 변경.
    // this.onMoreEvent(this.baseEventSeq);
  }
  onScrollReachEnd(event: any) {
    this.setEventMoreInit();
    if (!!this.snackBarPreviewEvent) {
      this.snackBarPreviewEvent.dismiss();
    }

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

  /** More Event */
  onMoreEvent(seq: number) {
    if (this.scrollUpinit && this.eventRemain) {
      this.eventMorePosition = this.psChatContent.directiveRef.elementRef.nativeElement.scrollHeight;

      this.store.dispatch(
        EventStore.info({
          roomSeq: this.roomInfo.roomSeq,
          baseSeq: seq,
          requestCount:
            environment.productConfig.CommonSetting.eventRequestDefaultCount
        })
      );
    }
  }

  /** Send Event */
  async onSendMessage(message: string) {
    this.setEventMoreInit();

    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;
      }
    }

    if (!!this.isShowTranslation && this.destLocale.trim().length > 0) {
      /** CASE : Translation */
      const destLocale = this.destLocale;
      const original = message;
      const roomSeq = this.roomInfo.roomSeq;

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

      this.isTranslationProcess = true;
      this.commonApiService
        .translationSave({
          userSeq: this.loginRes.userSeq,
          deviceType: this.environmentsInfo.deviceType,
          token: this.loginRes.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.loginRes.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.logger.error(res);
            }
          }),
          catchError(error => of(this.logger.error(error)))
        )
        .subscribe(() => {
          this.isTranslationProcess = false;
        });
    } else if (!!this.selectedSticker) {
      /** CASE : Sticker */
      if (
        !!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 ? message.trim() : ''
      };
      this.store.dispatch(
        EventStore.send({
          senderSeq: this.loginRes.userSeq,
          req: {
            roomSeq: this.roomInfo.roomSeq,
            eventType: EventType.Sticker,
            sentMessage: JSON.stringify(stickerJson)
          }
        })
      );
      this.isShowStickerSelector = false;
      this.setStickerHistory(this.selectedSticker);
      this.selectedSticker = null;
    } else if (
      message.trim().length >
      environment.productConfig.CommonSetting.masstextLength
    ) {
      /** CASE : MASS TEXT */
      this.store.dispatch(
        EventStore.sendMass({
          senderSeq: this.loginRes.userSeq,
          req: {
            roomSeq: this.roomInfo.roomSeq,
            eventType: EventType.MassText,
            // sentMessage: message.replace(/\n/gi, '\r\n')
            sentMessage: message
          }
        })
      );
    } else {
      /** CASE : Normal Text */
      this.store.dispatch(
        EventStore.send({
          senderSeq: this.loginRes.userSeq,
          req: {
            roomSeq: this.roomInfo.roomSeq,
            eventType: EventType.Character,
            sentMessage: message
          }
        })
      );
    }
  }

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

  /** 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.loginRes.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginRes.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(fileInfo: FileEventJson) {
    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: {
        fileInfo,
        downloadUrl: this.sessionVerInfo.downloadUrl,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginRes.tokenString,
        userSeq: this.loginRes.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 && result.length > 0) {
            this.saveFile(value, result);
          } else {
            this.snackBarService.open(
              this.translateService.instant(
                'common.file.errors.failToSpecifyPath'
              ),
              this.translateService.instant('common.file.errors.label')
            );
          }
        })
        .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');
  }

  saveFile(
    value: {
      fileInfo: FileEventJson;
      fileDownloadItem: FileDownloadItem;
      type: string;
    },
    savePath?: string
  ) {
    this.commonApiService
      .fileTalkDownload({
        userSeq: this.loginRes.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginRes.tokenString,
        attachmentsSeq: value.fileInfo.attachmentSeq,
        fileDownloadItem: value.fileDownloadItem
      })
      .pipe(
        take(1),
        map(async rawBlob => {
          const mimeType = MimeUtil.getMimeFromExtension(
            FileUtil.getExtension(value.fileInfo.fileName)
          );
          const blob = rawBlob.slice(0, rawBlob.size, mimeType);

          FileUtil.fromBlobToBuffer(blob)
            .then(buffer => {
              this.nativeService
                .saveFile(buffer, value.fileInfo.fileName, mimeType, savePath)
                .then(result => {
                  if (!!result) {
                    this.snackBarService.open(
                      this.translateService.instant(
                        'common.file.results.savedToPath',
                        {
                          path: result
                        }
                      ),
                      '',
                      {
                        duration: 3000,
                        verticalPosition: 'bottom'
                      }
                    );
                  } else {
                    this.snackBarService.openFromComponent<
                      AlertSnackbarComponent,
                      AlertSnackbarData
                    >(AlertSnackbarComponent, {
                      data: {
                        html: this.translateService.instant(
                          'common.file.errors.failToSave'
                        ),
                        buttonText: this.translateService.instant(
                          'common.file.errors.label'
                        )
                      }
                    });
                  }
                })
                .catch(reason => {
                  this.snackBarService.openFromComponent<
                    AlertSnackbarComponent,
                    AlertSnackbarData
                  >(AlertSnackbarComponent, {
                    data: {
                      html: this.translateService.instant(
                        'common.file.errors.failToSave'
                      ),
                      buttonText: this.translateService.instant(
                        'common.file.errors.label'
                      )
                    }
                  });
                });
            })
            .catch(reason => {
              this.logger.error('download', reason);
            });
        }),
        finalize(() => {
          setTimeout(() => {
            value.fileDownloadItem.downloadingProgress$ = undefined;
          }, 1000);
        })
      )
      .subscribe();
  }

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

    const info = {
      senderSeq: this.loginRes.userSeq,
      roomSeq: this.roomInfo.roomSeq
    };

    const allObservables: Observable<FileTalkSaveResponse>[] = [];

    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.dialogService.open<
          AlertDialogComponent,
          AlertDialogData,
          AlertDialogResult
        >(AlertDialogComponent, {
          width: '360px',
          data: {
            title: '',
            message: this.translateService.instant(
              'common.file.errors.oversize',
              {
                maxSize: fileAllowSize
              }
            )
          }
        });
        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.dialogService.open<
        AlertDialogComponent,
        AlertDialogData,
        AlertDialogResult
      >(AlertDialogComponent, {
        data: {
          title: 'Alert',
          html: `${this.translateService.instant(
            'common.file.errors.notSupporedType'
          )} ${
            checkExt.reject.length > 0
              ? '<br/>(' + checkExt.reject.join(',') + ')'
              : ''
          }`
        }
      });

      return;
    }

    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.loginRes.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginRes.tokenString,
        roomSeq: this.roomInfo.roomSeq,
        file: fileUploadItem.file,
        fileName: fileUploadItem.file.name,
        thumb: thumbnail,
        fileUploadItem
      };

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

    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
                }
              })
            );
          }
        },
        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();
          }
        },
        () => {
          this.fileUploadQueue.onUploadComplete();
        }
      );
  }

  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.loginRes,
      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'
                    ),
                    '확인'
                  );
                  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.loginRes.userSeq,
                    deviceType: this.environmentsInfo.deviceType,
                    token: this.loginRes.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.loginRes.userSeq,
                    deviceType: this.environmentsInfo.deviceType,
                    token: this.loginRes.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 'REPLAY':
        {
          const result = await this.dialogService.open<
            CreateChatDialogComponent,
            CreateChatDialogData,
            CreateChatDialogResult
          >(CreateChatDialogComponent, {
            width: '600px',
            data: {
              type: UserSelectDialogType.MessageForward,
              title: this.translateService.instant('chat.forwardEventTo'),
              ignoreRoom: [this.roomInfo]
            }
          });

          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.loginRes.userSeq,
                  req: {
                    roomSeq: '-999',
                    eventType: message.type,
                    sentMessage: message.sentMessage
                  },
                  trgtUserSeqs: userSeqs,
                  trgtRoomSeq: roomSeq
                })
              );
            }
          }
        }
        break;
      case 'REPLAY_TO_ME':
        {
          if (this.loginRes.talkWithMeBotSeq > -1) {
            this.store.dispatch(
              EventStore.forward({
                senderSeq: this.loginRes.userSeq,
                req: {
                  roomSeq: '-999',
                  eventType: message.type,
                  sentMessage: message.sentMessage
                },
                trgtUserSeqs: [this.loginRes.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.roomInfo.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.roomInfo.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 result = await this.dialogService.open<
            CreateChatDialogComponent,
            CreateChatDialogData,
            CreateChatDialogResult
          >(CreateChatDialogComponent, {
            width: '600px',
            data: {
              type: UserSelectDialogType.EditChatMember,
              title: this.translateService.instant('chat.modifyRoomMember'),
              curRoomUser: this.userInfoList.filter(
                user => user.seq !== this.loginRes.userSeq && user.isJoinRoom
              )
            }
          });

          if (!!result && !!result.choice && result.choice) {
            const userSeqs: number[] = this.userInfoList.map(userInfo => {
              if (userInfo.isJoinRoom) {
                return 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
              userSeqs.push(this.loginRes.userSeq);

              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.userInfoList
                .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.roomInfo
            }
          });

          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) {
    if (
      this.roomInfo.roomType !== RoomType.Allim &&
      this.roomInfo.roomType !== RoomType.Bot &&
      this.roomInfo.roomType !== RoomType.Link &&
      this.roomInfo.roomType !== RoomType.Allim_Elephant &&
      this.roomInfo.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.searchedList = [];
      this.searchedFocusEvent = null;
      this.searchText = '';
    }
  }
  onCloseSearchArea() {
    this.isShowSearchArea = false;
    this.searchedList = [];
    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({
        roomSeq: this.roomInfo.roomSeq,
        baseSeq: this.eventList[0].seq,
        requestCount:
          environment.productConfig.CommonSetting.eventRequestDefaultCount * 2
      })
    );

    // this.doSearchTextInEvent(searchText);
  }
  doSearchTextInEvent(searchText: string, baseSeq?: number): void {
    this.searchedList = this.eventList.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.searchedList && this.searchedList.length > 0) {
      this.searchTotalCount = this.searchedList.length;

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

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

      this.goSearchPosition(this.searchedFocusEvent.seq);
    } else {
      this.searchTotalCount = 0;
      this.searchCurrentIndex = 0;

      this.searchedFocusEvent = null;
    }
  }
  onPrevSearch() {
    this.searchedList.forEach((event, index) => {
      if (event.seq === this.searchedFocusEvent.seq && index > 0) {
        this.searchCurrentIndex = this.searchCurrentIndex - 1;
        this.searchedFocusEvent = this.searchedList[index - 1];
        this.goSearchPosition(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.searchedList.length) {
      this.searchedFocusEvent = this.searchedList[this.searchCurrentIndex];
      this.searchCurrentIndex = this.searchCurrentIndex + 1;
      this.goSearchPosition(this.searchedFocusEvent.seq);
    }
  }
  onSearchAndPrev() {
    if (
      !!this.searchText &&
      this.searchText.trim().length > 0 &&
      this.eventRemain
    ) {
      this.moreSearchProcessing = true;
      this.eventMorePosition = this.psChatContent.directiveRef.elementRef.nativeElement.scrollHeight;

      // Case :: retrieve event infos step by step until include searchtext in event..
      this.store.dispatch(
        EventStore.infoForSearch({
          req: {
            roomSeq: this.roomInfo.roomSeq,
            baseSeq: this.eventList[0].seq,
            requestCount:
              environment.productConfig.CommonSetting.eventRequestDefaultCount
          },
          searchText: this.searchText
        })
      );
    }
  }
  goSearchPosition(eventSeq: number) {
    if (this.psChatContent.directiveRef) {
      this.psChatContent.directiveRef.update();

      const element = document.getElementById(eventSeq.toString());
      if (!!element) {
        setTimeout(() => {
          this.psChatContent.directiveRef.scrollToTop(element.offsetTop - 200);
        });
      }
    }
  }

  /** 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.loginRes.userSeq,
        req: {
          roomSeq: this.roomInfo.roomSeq,
          eventType: params.translationType,
          sentMessage
        }
      })
    );

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