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

import * as AppStore from '@app/store';
import { tap, map, take, finalize } from 'rxjs/operators';
import { FileUtil, MimeUtil } 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 {
  SnackBarService,
  AlertSnackbarComponent,
  AlertSnackbarData
} from '@ucap-webmessenger/ui';
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 { TranslateService } from '@ngx-translate/core';

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 {
  filteredList: FileInfoTotal[] = [];
  fileInfoTotal: FileInfoTotal[];
  fileInfoList: FileInfo[];
  fileInfoListSubscription: Subscription;

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

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

  FileType = FileType;
  currentTabIndex = 0;

  thumbBaseUrl: string;

  constructor(
    private store: Store<any>,
    private sessionStorageService: SessionStorageService,
    private commonApiService: CommonApiService,
    private fileProtocolService: FileProtocolService,
    private translateService: TranslateService,
    private snackBarService: SnackBarService,
    @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
    @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 {
    return this.commonApiService.urlForFileTalkDownload(
      {
        userSeq: this.loginRes.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginRes.tokenString,
        attachmentsSeq: fileInfo.info.seq
      },
      this.sessionVerinfo.downloadUrl
    );
  }

  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
      );
    } 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.selectedFile = fileInfo;
  }

  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.commonApiService
      .fileTalkDownload({
        userSeq: this.loginRes.userSeq,
        deviceType: this.environmentsInfo.deviceType,
        token: this.loginRes.tokenString,
        attachmentsSeq: fileInfo.info.seq,
        fileDownloadItem: fileInfo.fileDownloadItem
      })
      .pipe(
        take(1),
        map(async rawBlob => {
          const mimeType = MimeUtil.getMimeFromExtension(
            FileUtil.getExtension(fileInfo.info.name)
          );
          const blob = rawBlob.slice(0, rawBlob.size, mimeType);

          FileUtil.fromBlobToBuffer(blob)
            .then(buffer => {
              /** download check */
              this.fileProtocolService
                .downCheck({
                  seq: fileInfo.info.seq
                })
                .pipe(take(1))
                .subscribe();

              this.nativeService
                .saveFile(buffer, fileInfo.info.name, mimeType)
                .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(() => {
            fileInfo.fileDownloadItem.downloadingProgress$ = undefined;
          }, 1000);
        })
      )
      .subscribe();
  }

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