import { HttpClient } from 'aurelia-fetch-client';
import { Router } from 'aurelia-router';
import { autoinject, bindable, computedFrom, useView } from 'aurelia-framework';
import { DialogController } from "aurelia-dialog";
import { Config } from '../../../config';
import { Extensions } from '../../../constants/constants';
import { RemoteFileStorage } from '../../../services/file-storage-service';

type FilePreviewerModel = { fileExtension: string, fileUrl: string, fileName?: string, isBlob?: boolean };

@autoinject
@useView('./file-previewer.html')
export class FilePreviewer {
  @bindable
  private loadTimeout = 3000;
  private iframeRef: HTMLIFrameElement;
  private originalUrl: string;
  private fileName: string
  private model: FilePreviewerModel
  private timer: NodeJS.Timeout;
  private isLoading = true;
  private canDownloadFiles = true;
  private isBlob = false;
  
  constructor(private dialogController: DialogController, private router: Router, private config: Config, private httpClient: HttpClient, private fileStorageService: RemoteFileStorage.Service) { 
    
  }

  public async activate(model: FilePreviewerModel) {
    this.model = model;
    this.isBlob = model.isBlob;
    this.canDownloadFiles = this.fileStorageService.canDownloadFiles;
    this.originalUrl = await this.fileStorageService.fileUrl(model.fileUrl);
  }

  public attached() {
    if (this.iframeRef != null) {
      this.iframeRef.onload = () => {
        this.markIframeLoaded();
      }

      this.loadIframe();
    }
    this.fileName = this.model.fileUrl.split('/').last();
  }

  public detached() {
    clearTimeout(this.timer);
  }

  private loadIframe() {
    this.isLoading = true;
    this.timer = setTimeout(() => {
      this.loadIframe();
    }, this.loadTimeout)

    try {
      this.iframeRef.src = this.getUrlFrame();
    } catch (e) {
      // Google docs viewer sometimes sends an error when displaying.
      // Catch this and mark as loaded
      this.markIframeLoaded();
    }
  }

  private markIframeLoaded() {
    this.isLoading = false;
    clearTimeout(this.timer);
  }

  @computedFrom("model.fileExtension")
  private get isPictureOrGif() {
    return Extensions.picture.includes(this.model.fileExtension) || this.model.fileExtension == 'gif'
  }
  @computedFrom("model.fileExtension")
  private get isOther() {
    return Extensions.other.includes(this.model.fileExtension)
  }
  @computedFrom("model.fileExtension")
  private get isOffice() {
    return Extensions.office.includes(this.model.fileExtension)
  }
  @computedFrom('isOffice', 'isPictureOrGif', 'isOther', 'isFromLocalStorage', 'isBlob')
  private get isNotSupported() {
    return false == (this.isOffice || this.isPictureOrGif || this.isOther || this.isBlob)
  }
  // @computedFrom('isOffice', 'isPictureOrGif', 'isOther', 'isFromLocalStorage')
  // protected get isNotSupported() {
  //   if (this.isFromLocalStorage) {
  //     return false == (this.isPictureOrGif || this.isOther);
  //   }
  //   return false == (this.isOffice || this.isPictureOrGif || this.isOther)
  // }
  @computedFrom('originalUrl')
  private get isFromLocalStorage() {
    return this.originalUrl.startsWith(this.config.globalConfig.remoteServiceName);
  }

  private getUrlFrame(): string {
    if (this.isNotSupported) {
      return '';
    }
    if (this.isPictureOrGif || this.isBlob || (document.baseURI.includes('localhost') && this.isOther && this.fileStorageService.secure)) {
      // Images can be shown
      return this.originalUrl;
    }
    if (this.isOffice || this.isOther) {
      //Trick to force embeded previewer to read the given url every time (Used if url is same but content has changed since)
      let fileUrl = new URL(this.originalUrl);
      // fileUrl.searchParams.append("dt", new Date().toISOString());
      if (this.isOffice) {
        return `https://view.officeapps.live.com/op/embed.aspx?src=${fileUrl.href}`;
      }
      else {
        return `https://docs.google.com/viewerng/viewer?url=${fileUrl.href}&embedded=true`;
      }
    }
    return '';
  }

  public async download() {
    this.fileStorageService.download(this.model.fileUrl);
  }
}
