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

import {
  Info,
  EventType,
  InfoResponse,
  EventJson,
  FileEventJson,
  MassTranslationEventJson
} from '@ucap-webmessenger/protocol-event';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { UserInfo, RoomInfo, RoomType } from '@ucap-webmessenger/protocol-room';
import { NGXLogger } from 'ngx-logger';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { FileInfo } from '../models/file-info.json';
import { DatePipe } from '@angular/common';
import moment from 'moment';
import { FileDownloadItem } from '@ucap-webmessenger/api';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'ucap-chat-messages',
  templateUrl: './messages.component.html',
  styleUrls: ['./messages.component.scss']
})
export class MessagesComponent implements OnInit {
  @Input()
  loginRes: LoginResponse;
  @Input()
  roomInfo: RoomInfo;
  @Input()
  set eventList(elist: Info<EventJson>[]) {
    if (!!elist && elist.length > 0) {
      this.firstEventSeq = elist[0].seq;
    }

    this.messages = elist;
  }
  @Input()
  searchedList: Info<EventJson>[];
  @Input()
  eventInfoStatus?: InfoResponse;
  @Input()
  eventRemain: boolean;
  @Input()
  userInfos?: UserInfo[];
  @Input()
  sessionVerInfo: VersionInfo2Response;
  @Input()
  isShowUnreadCount = true;
  @Input()
  clearReadHere: boolean;
  @Input()
  minShowReadHere = 10;
  @Input()
  initRoomLastEventSeq: number;
  @Input()
  translationSimpleview = false;

  @Output()
  openProfile = new EventEmitter<number>();
  @Output()
  moreEvent = new EventEmitter<number>();
  @Output()
  massDetail = new EventEmitter<number>();
  @Output()
  massTranslationDetail = new EventEmitter<{
    message: Info<MassTranslationEventJson>;
    contentsType: string;
  }>();
  @Output()
  fileViewer = new EventEmitter<FileEventJson>();
  @Output()
  save = new EventEmitter<{
    fileInfo: FileEventJson;
    fileDownloadItem: FileDownloadItem;
    type: string;
  }>();
  @Output()
  contextMenu = new EventEmitter<{
    event: MouseEvent;
    message: Info<EventJson>;
    type?: string;
  }>();

  messages: Info<EventJson>[];

  EventType = EventType;
  profileImageRoot: string;
  moment = moment;

  firstEventSeq = 0;
  existReadHere = false;

  constructor(
    private logger: NGXLogger,
    private datePipe: DatePipe,
    private translateService: TranslateService
  ) {}

  ngOnInit() {
    this.profileImageRoot =
      this.profileImageRoot || this.sessionVerInfo.profileRoot;
  }

  /**
   * UserInfo getter
   */
  getUserName(seq: number): string {
    if (!this.userInfos) {
      return '';
    }

    const userInfo: UserInfo[] = this.userInfos.filter(
      user => user.seq === seq
    );
    if (!!userInfo && userInfo.length > 0) {
      return userInfo[0].name;
    }
    return '(알수없는 사용자)';
  }
  getUserProfile(seq: number): string {
    if (!this.userInfos) {
      return '';
    }

    const userInfo: UserInfo[] = this.userInfos.filter(
      user => user.seq === seq
    );
    if (!!userInfo && userInfo.length > 0) {
      return userInfo[0].profileImageFile;
    }
    return '';
  }
  getEventSearched(seq: number): boolean {
    return (
      !!this.searchedList &&
      this.searchedList.filter(event => event.seq === seq).length > 0
    );
  }

  getUnreadCount(message: Info<EventJson>): string | number {
    const unreadCnt = this.userInfos.filter(user => {
      if (message.senderSeq === user.seq) {
        // 본인 글은 unreadCount 에 포함하지 않는다.
        return false;
      }
      return user.lastReadEventSeq < message.seq;
    }).length;
    return unreadCnt === 0 ? '' : unreadCnt;
  }

  /**
   * 정보성 Event 인지 판단.
   * @description 정보성 event 일 경우 프로필, 일시 를 표현하지 않는다.
   * Edit with reducers.ts / sync / updateRoomForNewEventMessage
   */
  getIsInformation(info: Info<EventJson>) {
    if (
      info.type === EventType.Join ||
      info.type === EventType.Exit ||
      info.type === EventType.ForcedExit ||
      info.type === EventType.RenameRoom ||
      info.type === EventType.NotificationForTimerRoom ||
      info.type === EventType.GuideForRoomTimerChanged
    ) {
      return true;
    }
    return false;
  }

  /** Date Splitter show check */
  getDateSplitter(curIndex: number): boolean {
    if (curIndex === 0) {
      return true;
    }
    if (curIndex > 0) {
      return (
        this.datePipe.transform(
          moment(this.messages[curIndex].sendDate).toDate(),
          'yyyyMMdd'
        ) !==
        this.datePipe.transform(
          moment(this.messages[curIndex - 1].sendDate).toDate(),
          'yyyyMMdd'
        )
      );
    }
    return false;
  }

  getReadHere(messageIndex: number): boolean {
    if (
      !!this.roomInfo &&
      !!this.roomInfo.lastReadEventSeq &&
      this.initRoomLastEventSeq - this.roomInfo.lastReadEventSeq >
        this.minShowReadHere
    ) {
      if (
        this.roomInfo.roomType === RoomType.Single ||
        this.roomInfo.roomType === RoomType.Multi
      ) {
        if (!this.roomInfo.isTimeRoom) {
          if (
            this.messages[messageIndex].seq ===
            this.roomInfo.lastReadEventSeq + 1
          ) {
            this.existReadHere = true;
            return true;
          }
        }
      }
    }
    return false;
  }

  getStringReadHereMore(): string {
    let rtnStr = '';
    rtnStr = this.translateService.instant('chat.event.moreUnreadEventsWith', {
      countOfUnread: this.firstEventSeq - (this.roomInfo.lastReadEventSeq + 1)
    });
    return rtnStr;
  }

  onClickOpenProfile(userSeq: number) {
    this.openProfile.emit(userSeq);
  }

  onClickMore(event: any) {
    event.preventDefault();
    event.stopPropagation();

    this.moreEvent.emit(this.messages[0].seq);
  }

  /** [Event] MassTalk Detail View */
  onMassDetail(value: number) {
    this.massDetail.emit(value);
  }

  onMassTranslationDetail(params: {
    message: Info<MassTranslationEventJson>;
    contentsType: string;
  }) {
    this.massTranslationDetail.emit(params);
  }

  /** [Event] Image Viewer */
  onFileViewer(fileInfo: FileEventJson) {
    this.fileViewer.emit(fileInfo);
  }

  /** [Event] Attach File Save & Save As */
  onSave(value: {
    fileInfo: FileEventJson;
    fileDownloadItem: FileDownloadItem;
    type: string;
  }) {
    this.save.emit(value);
  }

  /** [Event] Context Menu */
  onContextMenu(event: {
    event: MouseEvent;
    message: Info<EventJson>;
    type?: string;
  }) {
    this.contextMenu.emit(event);
  }
}
