import {
  Component,
  OnInit,
  OnDestroy,
  Inject,
  ElementRef,
  ViewChild
} from '@angular/core';
import {
  FileInfo,
  FileDownloadInfo,
  FileType
} from '@ucap-webmessenger/protocol-file';
import { Subscription, combineLatest } from 'rxjs';
import { Store, select } from '@ngrx/store';

import * as AppStore from '@app/store';
import { tap } from 'rxjs/operators';
import { FileUtil } from '@ucap-webmessenger/core';
import { CommonApiService } from '@ucap-webmessenger/api-common';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
import {
  EnvironmentsInfo,
  KEY_ENVIRONMENTS_INFO,
  KEY_VER_INFO
} from '@app/types';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { UCAP_NATIVE_SERVICE, NativeService } from '@ucap-webmessenger/native';
import { NGXLogger } from 'ngx-logger';
import { FileDownloadItem } from '@ucap-webmessenger/api';
import { ModuleConfig } from '@ucap-webmessenger/api-common';
import { _MODULE_CONFIG } from 'projects/ucap-webmessenger-api-common/src/lib/config/token';
import { AppFileService } from '@app/services/file.service';

export interface FileInfoTotal {
  info: FileInfo;
  checkInfo: FileDownloadInfo[];
  fileDownloadItem: FileDownloadItem;
}

@Component({
  selector: 'app-layout-chat-right-drawer-album-box',
  templateUrl: './album-box.component.html',
  styleUrls: ['./album-box.component.scss']
})
export class AlbumBoxComponent implements OnInit, OnDestroy {
  @ViewChild('videoPlayer', { static: false })
  videoPlayer: ElementRef<HTMLVideoElement>;

  filteredList: FileInfoTotal[] = [];
  fileInfoTotal: FileInfoTotal[];
  fileInfoList: FileInfo[];
  fileInfoListSubscription: Subscription;

  selectedFile: FileInfoTotal;
  selectedFileList: FileInfoTotal[] = [];

  loginRes: LoginResponse;
  environmentsInfo: EnvironmentsInfo;
  sessionVerinfo: VersionInfo2Response;

  FileType = FileType;
  currentTabIndex = 0;

  thumbBaseUrl: string;

  playable = true;

  urlList: string[];
  currentIndex = 0;

  constructor(
    private store: Store<any>,
    private sessionStorageService: SessionStorageService,
    private commonApiService: CommonApiService,
    @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
    private appFileService: AppFileService,
    @Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig,
    private logger: NGXLogger
  ) {
    this.loginRes = this.sessionStorageService.get<LoginResponse>(
      KEY_LOGIN_RES_INFO
    );
    this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
      KEY_ENVIRONMENTS_INFO
    );
    this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
      KEY_VER_INFO
    );

    this.thumbBaseUrl = `${this.moduleConfig.hostConfig.protocol}://${
      this.moduleConfig.hostConfig.domain
    }:${String(this.moduleConfig.hostConfig.port)}`;
  }

  ngOnInit() {
    this.fileInfoListSubscription = combineLatest([
      this.store.pipe(select(AppStore.MessengerSelector.RoomSelector.roomInfo)),
      this.store.pipe(
        select(AppStore.MessengerSelector.EventSelector.selectAllFileInfoList)
      ),
      this.store.pipe(
        select(
          AppStore.MessengerSelector.EventSelector.selectAllFileInfoCheckList
        )
      )
    ])
      .pipe(
        tap(() => (this.fileInfoTotal = [])),
        tap(([roomInfo, fileInfoList, fileInfoCheckList]) => {
          this.fileInfoList = fileInfoList.filter(fileInfo => {
            if (
              !!roomInfo &&
              fileInfo.roomSeq === roomInfo.roomSeq &&
              (fileInfo.type === FileType.Image ||
                fileInfo.type === FileType.Video)
            ) {
              return true;
            } else {
              return false;
            }
          });

          this.fileInfoList.map(fileInfo => {
            this.fileInfoTotal.push({
              info: fileInfo,
              checkInfo: fileInfoCheckList.filter(
                checkInfo => checkInfo.seq === fileInfo.seq
              ),
              fileDownloadItem: new FileDownloadItem()
            });
          });

          this.onSelectedIndexChange(this.currentTabIndex);
        })
      )
      .subscribe();
  }

  ngOnDestroy(): void {
    if (!!this.fileInfoListSubscription) {
      this.fileInfoListSubscription.unsubscribe();
    }
  }

  getExtention(name: string): string {
    return FileUtil.getExtension(name);
  }

  getImageUrl(fileInfo: FileInfoTotal): string {
    if(FileType.Bundle === fileInfo.info.type && !!this.urlList) {
      return this.urlList[this.currentIndex];
    }
    return this.commonApiService.urlForFileTalkDownload(
      {
        userSeq: this.loginRes.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginRes.tokenString,
        attachmentsSeq: fileInfo.info.seq
      },
      this.sessionVerinfo.downloadUrl
    );
  }

  getThumbnailForBundle(info: Info<BundleImageEventJson>, index: number) {
    return `${info.sentMessageJson.baseUrl}${info.sentMessageJson.thumbUrls[index]}`;
  }

  onErrorThumbnail(el: HTMLElement, fileInfo: FileInfoTotal): void {
    const iconEl = document.createElement('div');
    iconEl.setAttribute(
      'class',
      'mime-icon light ico-' + this.getExtention(fileInfo.info.name)
    );
    iconEl.innerHTML = `<div class="ico"></div>`;
    el.replaceWith(iconEl);
  }

  onSelectedIndexChange(index: number) {
    this.selectedFile = null;
    this.currentTabIndex = index;
    if (this.currentTabIndex === 0) {
      // Image
      this.filteredList = this.fileInfoTotal.filter(
        fileInfo => 
          fileInfo.info.type === FileType.Image ||
          fileInfo.info.type === FileType.Bundle
      );
    } else {
      // Video
      this.filteredList = this.fileInfoTotal.filter(
        fileInfo => fileInfo.info.type === FileType.Video
      );
    }
  }

  onClickImage(event: MouseEvent, fileInfo: FileInfoTotal) {
    if (!!event) {
      event.preventDefault();
      event.stopPropagation();
    }

    this.playable = true;
    this.selectedFile = fileInfo;

    if (FileType.Bundle === fileInfo.info.type) {
      this.urlList = [];
      const bundleJson = fileInfo.info.sentMessageJson as BundleImageEventJson;
      bundleJson.thumbUrls.forEach((thumb, index) => {
          this.urlList.push(
            `${bundleJson.baseUrl}${bundleJson.thumbUrls[index]}`
              .replace('WebFile', 'AttFile')
              .replace('.thumb.jpg','')
          );
      });
      this.currentIndex = 0;
    } else {
      this.urlList = undefined;
      this.currentIndex = 0;
    }
  }

  getCheckItem(fileInfo: FileInfoTotal) {
    if (this.selectedFileList) {
      if (
        this.selectedFileList.filter(
          info => info.info.seq === fileInfo.info.seq
        ).length > 0
      ) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
  onCheckItem(value: boolean, fileInfo: FileInfoTotal) {
    if (value) {
      this.onClickImage(undefined, fileInfo);
      this.selectedFileList.push(fileInfo);
    } else {
      this.selectedFileList = this.selectedFileList.filter(
        info => info.info.seq !== fileInfo.info.seq
      );
    }
  }

  onClickDownload(fileInfo: FileInfoTotal) {
    this.appFileService.fileTalkDownlod({
      req: {
        userSeq: this.loginRes.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginRes.tokenString,
        attachmentsSeq: fileInfo.info.seq,
        fileDownloadItem: fileInfo.fileDownloadItem
      },
      fileName: fileInfo.info.name
    });
  }

  onClickDownloadAll(): void {
    this.selectedFileList.forEach(fileInfo => {
      this.onClickDownload(fileInfo);
    });
  }

  onClickOpenDownloadFolder(): void {
    this.nativeService
      .openDefaultDownloadFolder()
      .then(result => {
        if (!!result) {
        } else {
          throw new Error('response Error');
        }
      })
      .catch(reason => {
        this.logger.error(reason);
      });
  }

  onLoadedDataVideo(): void {
    if (
      0 === this.videoPlayer.nativeElement.videoWidth ||
      0 === this.videoPlayer.nativeElement.videoHeight
    ) {
      this.playable = false;
    }
  }

  onclickBundleImagePrev() {
    if (!this.urlList || 0 === this.urlList.length || 0 === this.currentIndex) {
      return;
    }
    this.currentIndex--;
  }

  onClickBundleImageNext() {
    if (
      !this.urlList || 
      0 === this.urlList.length ||
      this.urlList.length - 1 <= this.currentIndex
    ) {
      return;
    }
    this.currentIndex++;
  }
}