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

import { Store, select } from '@ngrx/store';
import { map, catchError, takeUntil, take } from 'rxjs/operators';
import { of, Subject } from 'rxjs';

import {
  Info,
  EventJson,
  EventType,
  FileType,
  StickerEventJson
} from '@ucap/protocol-event';
import {
  UserInfo as RoomUserInfo,
  UserInfoShort as RoomUserInfoShort,
  RoomInfo
} from '@ucap/protocol-room';
import { LoginResponse } from '@ucap/protocol-authentication';
import { LoginSession } from '@ucap/core';

import { I18nService } from '@ucap/ng-i18n';
import { LocalStorageService } from '@ucap/ng-web-storage';
import { LogService } from '@ucap/ng-logger';
import { CommonApiService } from '@ucap/ng-api-common';

import { AppAuthenticationService } from '@app/services/app-authentication.service';

import { MatDialog } from '@angular/material/dialog';
import { LoginSelector } from '@ucap/ng-store-authentication';
import { MassTalkDownloadRequest } from '@ucap/api-common';
import { StatusCode } from '@ucap/api';
import { Dictionary } from '@ngrx/entity';

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

  @Input()
  isMe = false;
  @Input()
  senderInfo: RoomUserInfoShort | RoomUserInfo;
  @Input()
  defaultProfileImage = '';
  @Input()
  profileImageRoot = '';

  @Input()
  dateChanged = false;
  @Input()
  unreadCount: number;

  loginSession: LoginSession;
  loginRes: LoginResponse;

  EventType = EventType;

  //////////////////////////////////
  @Input()
  messageType: string;
  @Input()
  highlight = false;
  @Input()
  existReadToHere = false;
  @Input()
  fileType: FileType;

  private ngOnDestroySubject: Subject<boolean>;
  constructor(
    private store: Store<any>,
    private i18nService: I18nService,
    private dialog: MatDialog,
    private localStorageService: LocalStorageService,
    private logService: LogService,
    private appAuthenticationService: AppAuthenticationService,
    private commonApiService: CommonApiService,
    private changeDetectorRef: ChangeDetectorRef
  ) {}

  ngOnInit() {
    this.ngOnDestroySubject = new Subject<boolean>();
    this.store
      .pipe(takeUntil(this.ngOnDestroySubject), select(LoginSelector.loginRes))
      .subscribe((loginRes) => {
        this.loginRes = loginRes;
      });
    this.appAuthenticationService
      .getLoginSession$()
      .pipe(takeUntil(this.ngOnDestroySubject))
      .subscribe((loginSession) => (this.loginSession = loginSession));
  }

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

  ngAfterViewInit(): void {}

  /**
   * 정보성 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;
  }

  /**
   * Get Sticker image.
   */
  getStickerImage(message: Info<EventJson>): string {
    if (!!message.sentMessageJson) {
      return `assets/sticker/sticker_s_${
        (message.sentMessageJson as StickerEventJson).file
      }.png`;
    } else {
      return '';
    }
  }

  /**
   * Url link Open Event.
   */
  onOpenLink(url: string): void {
    console.log('onOpenLink', url);
  }

  /**
   * Detail view > Mass text.
   */
  onOpenMassDetail(eventMassSeq: number): void {
    const req = {
      userSeq: this.loginRes.userSeq,
      deviceType: this.loginSession.deviceType,
      eventMassSeq: Number(eventMassSeq),
      token: this.loginRes.tokenString
    } as MassTalkDownloadRequest;

    this.commonApiService
      .massTalkDownload(req)
      .pipe(
        take(1),
        map((res) => {
          if (res.statusCode === StatusCode.Success) {
            console.log('massTalkDownload', res.content);
            // const result = this.dialog.open<
            //   MassDetailComponent,
            //   MassDetailDialogData
            // >(MassDetailComponent, {
            //   data: {
            //     title: this.i18nService.t('chat.detailView'),
            //     contents: res.content
            //   }
            // });
          } else {
            this.logService.error(
              `commonApiService] massTalkDownload ${res?.errorMessage}`
            );
          }
        }),
        catchError((error) => of({ error }))
      )
      .subscribe();
  }
}
