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

import { shakeAnimation } from 'angular-animations';

import {
  Info,
  EventType,
  InfoResponse,
  EventJson,
  FileEventJson,
  MassTranslationEventJson
} from '@ucap-webmessenger/protocol-event';
import { NGXLogger } from 'ngx-logger';
import moment from 'moment';
import { FileDownloadItem } from '@ucap-webmessenger/api';
import { RoomInfo } from '@ucap-webmessenger/protocol-room';
import { SelectFileInfo } from '@ucap-webmessenger/ui';

@Component({
  selector: 'ucap-chat-message-box',
  templateUrl: './message-box.component.html',
  styleUrls: ['./message-box.component.scss'],
  animations: [shakeAnimation()]
})
export class MessageBoxComponent implements OnInit, AfterViewInit {
  @Input()
  message: Info<EventJson>;

  @Input()
  mine = false;

  @Input()
  highlight = false;

  @Input()
  existReadToHere = false;

  @Input()
  dateChanged = false;

  @Input()
  senderName: string;

  @Input()
  profileImageRoot: string;

  @Input()
  profileImage: string;

  @Input()
  roomInfo: RoomInfo;

  @Input()
  translationSimpleview = false;

  @Input()
  unreadCount: number;

  @Output()
  openProfile = new EventEmitter<number>();

  @Output()
  massDetail = new EventEmitter<number>();

  @Output()
  massTranslationDetail = new EventEmitter<{
    message: Info<MassTranslationEventJson>;
    contentsType: string;
  }>();

  @Output()
  fileViewer = new EventEmitter<SelectFileInfo>();

  @Output()
  save = new EventEmitter<{
    fileInfo: FileEventJson;
    fileDownloadItem: FileDownloadItem;
    type: string;
  }>();

  @Output()
  contextMenu = new EventEmitter<{
    event: MouseEvent;
    message: Info<EventJson>;
    type?: string;
  }>();

  @ViewChild('mbContainer', { static: true })
  mbContainer: ElementRef<HTMLElement>;

  @ViewChild('mbChatRow', { static: true })
  mbChatRow: ElementRef<HTMLElement>;

  EventType = EventType;

  moment = moment;

  firstEventSeq = 0;
  existReadHere = false;
  shakeIt = false;

  get offsetTop() {
    return this.mbChatRow.nativeElement.offsetTop;
  }

  constructor(
    private elementRef: ElementRef<HTMLElement>,
    private changeDetectorRef: ChangeDetectorRef,
    private logger: NGXLogger
  ) {}

  ngOnInit() {
    this.mbContainer.nativeElement.classList.add('hide');
  }

  ngAfterViewInit(): void {
    this.elementRef.nativeElement.style.height = `${this.mbContainer.nativeElement.offsetHeight}px`;
    this.elementRef.nativeElement.style.maxHeight = `${this.mbContainer.nativeElement.offsetHeight}px`;
    this.mbContainer.nativeElement.classList.remove('hide');
  }

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

  onClickOpenProfile(event: MouseEvent, userSeq: number) {
    event.preventDefault();
    event.stopPropagation();

    this.openProfile.emit(userSeq);
  }

  /** [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: SelectFileInfo) {
    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: any, message: Info<EventJson>) {
    if (
      message.type === EventType.Translation ||
      message.type === EventType.MassTranslation
    ) {
      this.contextMenu.emit({ event: event.event, message, type: event.type });
    } else {
      this.contextMenu.emit({ event, message });
    }
  }

  shake() {
    this.shakeIt = false;
    this.changeDetectorRef.detectChanges();
    setTimeout(() => {
      this.shakeIt = true;
      this.changeDetectorRef.detectChanges();
    }, 1);
  }
}
