/* eslint-disable prefer-template,no-param-reassign */
import React, { Component } from 'react';
import { Upload, Icon, message, Modal } from 'antd';
import { queryOssSignature } from '../../services/resource';
import { Hotax } from '../../utils/config';
import { setSignature } from '../../utils/signature';
import styles from './index.less';

const Message = message;

// 允许上传的文件类型
const renderAccept = (accept) => {
  if (!accept) {
    return null;
  }
  if (['image', 'video', 'audio'].find(ext => ext === accept)) {
    return `${accept}/*`;
  }
  if (accept === 'zip') {
    return 'application/zip,application/x-zip,application/x-zip-compressed';
  }
  return `.${accept}`;
};

// 检查文件大小
const checkFileSize = (fileName, fileSize) => {
  if (fileSize > Hotax.FILE_MAX_SIZE * 1000 * 1000) {
    Message.error(`${fileName}文件大小超过${Hotax.FILE_MAX_SIZE}M!`);
    return false;
  }
  return true;
};

/**
 * 使用时间戳生成随机的文件名
 * @param fileName
 * @param fileCode
 * @returns {string}
 */
const getRandomFileName = (fileName, fileCode) => {
  const relativePath = fileCode ? fileCode.replace(/-/g, '/') + '/' : '';
  const separatorIndex = fileName.lastIndexOf('.');
  const suffix = fileName.substring(separatorIndex + 1, fileName.length);
  const randomFileName = (new Date()).getTime().toString() + Math.floor(Math.random() * 10000) + '.' + suffix;
  return `${relativePath}${randomFileName}`;
};

/**
 * 将传入文件对象处理成upload组件格式
 * @return {Array} [{}]
 */
const renderFileList = (fileList) => {
  return fileList.map((file, index) => {
    if (file.status === 'uploading') {
      return file;
    }
    return {
      url: file.url,
      path: file.path,
      thumbUrl: file.url,
      name: file.name,
      size: file.size,
      type: file.type,
      status: 'done',
      uid: index,
      processed: true, // 标记是否图片已处理
    };
  });
};

class Uploader extends Component {
  constructor(props) {
    super(props);
    this.state = {
      ossSign: {}, // 保存oss签名
      fileList: renderFileList(this.props.fileList), // 文件对象列表
      curFileName: '',
      previewImg: '',
      previewVisible: false,
    };
  }
  handleBeforeUpload = (file) => {
    const { fileCode } = this.props;
    if (!checkFileSize(file.name, file.size)) {
      return false;
    }
    return queryOssSignature({ fileName: file.name })
      .then((res) => {
        this.setState({
          ossSign: res.data || res,
          curFileName: getRandomFileName(file.name, fileCode),
        });
        if (res.data) {
          setSignature(res.data); // 保存签名到本地
        }
      });
  };
  handleOnChange = ({ fileList }) => {
    const { ossSign, curFileName } = this.state;
    const { onUpload, totalLimit } = this.props;
    const { dir, host } = ossSign;
    const newFileList = fileList.filter((file) => {
      if (file.status === 'error') {
        Message.error(`${file.name}上传失败!`); // 上传失败给出提示并去掉
        return false;
      }
      if (file.status === 'done' && !file.processed) {
        Message.success('上传成功');
        file.url = `${host}/${dir}${curFileName}`;
        file.path = `${dir}${curFileName}`;
        file.thumbUrl = file.url;
        file.processed = true;
      }
      return true;
    });
    this.setState({
      fileList: renderFileList(newFileList),
    });
    const uploaded = newFileList.filter((file) => {
      return file.status === 'done' && file.processed;
    });
    if (!uploaded.length) { return; }
    if (this.props.onChange) {
      this.props.onChange(uploaded.splice(0, totalLimit));
    } else {
      onUpload(uploaded.slice(0, totalLimit));
    }
  };
  handleOnRemove = (file) => {
    const newFileList = this.state.fileList.filter((item) => {
      return item.uid !== file.uid;
    });
    if (this.props.onChange) {
      this.props.onChange(newFileList);
    } else {
      this.props.onRemove(newFileList);
    }
  };
  handleOnPreview = (file) => {
    this.setState({
      previewImg: file.url || file.thumbUrl,
      previewVisible: true,
    });
  };
  handleCancelPreview = () => {
    this.setState({
      previewVisible: false,
    });
  };
  render() {
    const { multiple, accept, totalLimit, forbidden } = this.props;
    const { ossSign, fileList, curFileName, previewImg, previewVisible } = this.state;
    const { host, policy, accessid, signature, dir } = ossSign;

    const uploadProps = {
      action: host,
      headers: {
        Authorization: `OSS${accessid}:${signature}`,
      },
      data: {
        policy,
        signature,
        OSSAccessKeyId: accessid,
        key: `${dir}${curFileName}`,
        success_action_status: '200',
      },
      fileList,
      multiple,
      disabled: !!(forbidden || this.state.fileList.length >= totalLimit),
      accept: renderAccept(accept),
      listType: 'picture',
      beforeUpload: this.handleBeforeUpload,
      onPreview: this.handleOnPreview,
      onChange: this.handleOnChange,
      onRemove: this.handleOnRemove,
    };

    return (
      <div>
        <Upload.Dragger {...uploadProps}>
          <p className={styles.dragIcon}>
            <Icon type="inbox" />
          </p>
          <p className={styles.dragText}>点击或者拖拽图片到此区域进行上传</p>
          <p className={styles.dragHint}>{`支持jpg/png图片格式,大小需小于${Hotax.FILE_MAX_SIZE}M`}</p>
        </Upload.Dragger>
        <Modal
          visible={previewVisible}
          footer={null}
          onCancel={this.handleCancelPreview}
          width={650}
        >
          <img src={previewImg} alt="" style={{ width: '100%', marginTop: 20 }} />
        </Modal>
      </div>
    );
  }
}

export default Uploader;