import {Component, ElementRef, EventEmitter, Input, OnInit, Output, TemplateRef, ViewChild} from '@angular/core';
import {FileItem, FileUploader, ParsedResponseHeaders} from 'ng2-file-upload';
import {MsgService} from '../msg/msg.service';
import {environment} from '../../../environments/environment';
import {BsModalRef, BsModalService} from 'ngx-bootstrap';
import {AjaxService} from '../ajax/ajax.service';

@Component({
  selector: 'frame-uploader',
  templateUrl: './uploader.component.html'
})
export class UploaderComponent implements OnInit {
  @Input() uploadUrl: string;
  @Input() multiple = false;
  @Input() confirmMsg: string;
  @Input() successMsg: string;
  @Input() allowedFileType: [string];
  @Input() maxFileSize: number;
  @Input() uploadParams = {};
  @Input() templateFile: string;

  @Output() afterUpload = new EventEmitter<any>();
  @Output() beforeUpload = new EventEmitter<FileItem>();
  @Output() allUpload = new EventEmitter<any>();

  private requestparam: any;
  private threadId; any;
  private errorFlag = false;

  // 上传核心组件
  fileUploader: FileUploader;
  @ViewChild('elSimpleUpload', {static: false}) elSimpleUpload: ElementRef;
  @ViewChild('elMultipleUpload', {static: false}) elMultipleUpload: ElementRef;

  constructor(private bsService: BsModalService) {
  }

  ngOnInit(): void {
    this.fileUploader = new FileUploader({
      url: environment.uploadRoot + this.uploadUrl,
      allowedFileType: this.allowedFileType,
      method: 'post',
      maxFileSize: this.maxFileSize * 1024,
      isHTML5: true,
      autoUpload: true,
      removeAfterUpload: true
      // headers: [{ name: 'Access-Control-Allow-Origin', value: '*'}]
    });
    this.fileUploader.onBuildItemForm = this.onBuildItemForm.bind(this);
    this.fileUploader.onBeforeUploadItem = this.onBeforeUploadItem.bind(this);
    this.fileUploader.onCompleteItem = this.onCompleteItem.bind(this);
    this.fileUploader.onCompleteAll = this.onCompleteAll.bind(this);
    this.fileUploader.onAfterAddingAll = this.onAfterAddingAll.bind(this);
  }

  // 上传之前传递参数
  private onBuildItemForm(fileItem: FileItem, form: any) {
    fileItem.withCredentials = false;
    const data = Object.assign({}, this.uploadParams, this.requestparam);
    for (const v in data) {
      form.append(v, data[v]);
    }
  }

  private onBeforeUploadItem(fileItem: FileItem) {
    this.beforeUpload.emit(fileItem);
  }

  private onAfterAddingAll() {
    MsgService.showLoading();
  }

  private onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) {
    if (status === 404) {
      MsgService.errorAlert(`无法访问上传地址，请联系系统管理员！`);
      return;
    }

    if (status !== 200) {
      // 非正常返回，直接提示错误信息、
      MsgService.errorAlert(`文件上传出现异常，请稍后再试！`);
      return;
    }
    const ajax = JSON.parse(response);
    if (ajax.success === undefined || ajax.success === false) {
      MsgService.errorAlert(ajax.errorMsg);
      this.errorFlag = true;
    } else {

      // 判断是否是后台线程
      if (ajax.threadId) {
        this.threadId = ajax.threadId;
        // 如果返回的json有threadId，表示是一个后台线程
        MsgService.showThreadRunning(this.bsService, ajax.entity, {threadTitle: '文件已上传，正在解析处理'});
      }
      this.errorFlag = false;
      this.afterUpload.emit(ajax);
    }


  }

  private onCompleteAll() {
    if (this.multiple === true) {
      this.elMultipleUpload.nativeElement.value = '';
    } else {
      this.elSimpleUpload.nativeElement.value = '';
    }

    // 只有非线程的时候弹出提示信息
    if (!this.errorFlag && this.successMsg !== undefined && this.threadId === undefined) {
      MsgService.successAlert(this.successMsg);
      this.allUpload.emit(undefined);
    }
    MsgService.hideLoading();

  }

  /******************
   * 上传文件
   */
  uploadFiles(data?: any) {
    const fn = () => {
      this.requestparam = data;
      if (this.multiple === true) {
        this.elMultipleUpload.nativeElement.click();
      } else {
        this.elSimpleUpload.nativeElement.click();
      }
    };
    if (this.confirmMsg !== undefined) {
      MsgService.confirm(this.confirmMsg, fn);
    } else {
      fn.apply(undefined);
    }
  }


  downloadTempalte(fileName?: string) {
    if (fileName === undefined) {
      fileName = this.templateFile;
    }
    if (fileName === undefined) {
      return;
    }

    AjaxService.ajaxDownload('frame/template/download.htm', {file_name: fileName});
  }
}
