import { Component, OnInit, OnDestroy, Inject } from '@angular/core';

import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { NGXLogger } from 'ngx-logger';
import { FileEventJson } from '@ucap-webmessenger/protocol-event';
import { DeviceType, FileUtil, MimeUtil } from '@ucap-webmessenger/core';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { take, map, finalize, tap } from 'rxjs/operators';
import {
  SnackBarService,
  AlertSnackbarComponent,
  AlertSnackbarData
} from '@ucap-webmessenger/ui';
import { FileDownloadItem } from '@ucap-webmessenger/api';
import { CommonApiService } from '@ucap-webmessenger/api-common';
import { TranslateService } from '@ngx-translate/core';
import { FileProtocolService } from '@ucap-webmessenger/protocol-file';
import { select, Store } from '@ngrx/store';
import { Subscription } from 'rxjs';
import * as AppStore from '@app/store';

export interface FileViewerDialogData {
  fileInfo: FileEventJson;
  downloadUrl: string;
  userSeq: number;
  deviceType: DeviceType;
  token: string;
}

export interface FileViewerDialogResult {}

@Component({
  selector: 'app-layout-common-file-viewer',
  templateUrl: './file-viewer.dialog.component.html',
  styleUrls: ['./file-viewer.dialog.component.scss']
})
export class FileViewerDialogComponent implements OnInit, OnDestroy {
  loginResSubscription: Subscription;

  fileInfo: FileEventJson;
  downloadUrl: string;
  userSeq: number;
  deviceType: DeviceType;
  token: string;

  fileDownloadUrl: string;

  constructor(
    public dialogRef: MatDialogRef<
      FileViewerDialogData,
      FileViewerDialogResult
    >,
    @Inject(MAT_DIALOG_DATA) public data: FileViewerDialogData,
    @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
    private translateService: TranslateService,
    private snackBarService: SnackBarService,
    private commonApiService: CommonApiService,
    private fileProtocolService: FileProtocolService,
    private store: Store<any>,
    private logger: NGXLogger
  ) {
    this.fileInfo = data.fileInfo;
    this.downloadUrl = data.downloadUrl;
    this.userSeq = data.userSeq;
    this.deviceType = data.deviceType;
    this.token = data.token;

    this.fileDownloadUrl = this.commonApiService.urlForFileTalkDownload(
      {
        userSeq: this.userSeq,
        deviceType: this.deviceType,
        token: this.token,
        attachmentsSeq: this.fileInfo.attachmentSeq
      },
      this.downloadUrl
    );
  }

  ngOnInit() {
    this.loginResSubscription = this.store
      .pipe(
        select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
        tap(loginRes => {
          if (!loginRes) {
            this.onClosedViewer();
          }
        })
      )
      .subscribe();
  }

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

  onDownload(fileDownloadItem: FileDownloadItem): void {
    this.commonApiService
      .fileTalkDownload(
        {
          userSeq: this.userSeq,
          deviceType: this.deviceType,
          token: this.token,
          attachmentsSeq: this.fileInfo.attachmentSeq,
          fileDownloadItem
        },
        this.downloadUrl
      )
      .pipe(
        take(1),
        map(async rawBlob => {
          const mimeType = MimeUtil.getMimeFromExtension(this.fileInfo.fileExt);
          const blob = rawBlob.slice(0, rawBlob.size, mimeType);

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

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

  onClosedViewer(): void {
    this.dialogRef.close();
  }
}
