import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {ImagePicker, Toast} from 'antd-mobile';
import config from '@/config/config';
import {getToken} from '@/H5Public/utils/authority';


/**
 * 组件使用方法
 *
 * <Upload
 ref='upload'   this.refs.upload.handleSubmit()  调用子组件提交方法
 handleSubmit={this.submit1}   子组件提交后返回后端数据回调函数
 // rest={{disableDelete:true}}  基于antd-mobile，可使用antd自身属性---不是必填项
 />
 */

// 全局loadinng
let loadingCount = 0;

class Upload extends Component {
  constructor(props) {
    super(props)
    this.state = {
      files: [], // 图片文件
      urlList: [] // 后端返回图片地址
    }
  }

  componentDidMount() {
    // 回显
    const ImageArr = [];
    this.props.defaultFiles.map(item => {
      ImageArr.push({
        url: item
      })
    })
    this.setState({files: ImageArr})
  }

  // 图片压缩函数
  zipImage = (file) => {
    let fileSizeMb = file.size / 1024 / 1024;
    let fileName = file.name;
    if (fileSizeMb < this.props.fileSizeMb) {  // 1MB 以下的图片不需要压缩。
      this.uploadCall(file)
      return false;
    }
    let reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = (e) => {
      //这里的e.target.result就是转换后base64格式的图片文件
      let image = new Image(); //新建一个img标签（还没嵌入DOM节点)
      image.src = e.target.result;
      return image.onload = () => {
        let canvas = document.createElement('canvas');
        let context = canvas.getContext('2d');
        let imageWidth = image.width * 0.3;    //压缩后图片的大小
        let imageHeight = image.height * 0.3;
        let data = '';
        canvas.width = imageWidth;
        canvas.height = imageHeight;

        context.drawImage(image, 0, 0, imageWidth, imageHeight);
        data = canvas.toDataURL('image/jpeg');
        let zipFile = this.dataURLtoFile(data, fileName);
        this.uploadCall(zipFile)
      };
    };
  };
  //将base64转换为文件
  dataURLtoFile = (dataurl, filename) => {
    let arr = dataurl.split(',');
    let mime = arr[0].match(/:(.*?);/)[1];

    let bstr = atob(arr[1]);
    let n = bstr.length;
    let u8arr = new Uint8Array(n);
    while (n--) {
      u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type: mime});
  };
  // 上传本地
  onChange = (files) => {
    this.setState({files});
  }
  // 上传图片--方法
  uploadImg = (file, callback) => {
    const xhr = new XMLHttpRequest();
    const formData = new FormData();
    formData.append('file', file);
    if(config.version === 'bdk'){
      xhr.open('post', config.uploadUrl, true);
    }else{
      xhr.open('post', config.uploadUrl + "?token=" + getToken(), true);
    }
    xhr.setRequestHeader("Accept", "application/json;charset=UTF-8");
    xhr.setRequestHeader("Authorization", `bearer ${getToken()}`);
    xhr.send(formData);
    xhr.onreadystatechange = () => {
      if (xhr.readyState == 4 && xhr.status === 200) {
        const json = JSON.parse(xhr.responseText);
        callback(json.url)
      }
    }
  }
  // 上传后获取后端返回图片地址
  uploadCall = (item) => (
    this.uploadImg(item, (res) => {
      this.setState({urlList: [...this.state.urlList, res]}, () => {
        if (this.state.files.length === this.state.urlList.length) {
          Toast.hide()
          loadingCount = 0;
          const {handleSubmit, labelId = ''} = this.props;
          handleSubmit(this.state.urlList, labelId) // 把后端返回url传给父组件
        }
      })
    })
  )
  // 提交
  handleSubmit = () => {
    const {files} = this.state;
    Toast.loading('Loading...', 0);
    // 判断是否是回显的图片--不是则进行压缩
    const httpFiles = files.filter(item => item.url.startsWith('http')) // 回显图片
    const oldUrlArr = [];
    httpFiles.map(item => oldUrlArr.push(item.url))
    const Files = files.filter(item => !item.url.startsWith('http')) // 本地图片
    this.setState({urlList: oldUrlArr}, () => {
      if (Files.length == 0) {
        Toast.hide()
        loadingCount = 0;
        const {handleSubmit, labelId = ''} = this.props;
        handleSubmit(this.state.urlList, labelId) // 把后端返回url传给父组件
      }
      Files.map(item => {
        loadingCount++
        this.zipImage(item.file)
      })
    })
  }

  render() {
    const {files} = this.state;
    const {multiple, accept, length, readOnly, rest} = this.props;
    return (
      <div>
        <ImagePicker
          files={files}
          accept={accept}
          onChange={this.onChange}
          selectable={readOnly ? false : (files.length < length)}
          multiple={multiple}
          disableDelete={!!readOnly}
          {...rest}
        />
      </div>
    );
  }
}

Upload.propTypes = {
  multiple: PropTypes.bool, // 是否支持多选
  accept: PropTypes.string, // 上传格式限制
  length: PropTypes.number, // 最大支持上传张数
  handleSubmit: PropTypes.func.isRequired, // 上传函数
  rest: PropTypes.object,
  defaultFiles: PropTypes.array, // 初始值
  readOnly: PropTypes.bool,
  labelId: PropTypes.any  // 组件id 标识
}

Upload.defaultProps = {
  multiple: true, // 是否支持多选
  accept: 'image/*', // 上传格式限制
  length: 10, // 最大支持上传张数
  defaultFiles: [],
  readOnly: false,
  labelId: ''
}

export default Upload;
