/**
 * Created by liuqiang on 2017/6/3.
 */

import React from 'react';
import { Upload, Button, Icon, Progress, Modal } from '../../../../../components/mxa';
import staticDisplay from './StaticDisplay';
import { VIEW, EDIT } from '../../constant';
import { getSecurityToken, updateSecurityToken } from '../../../../service/CacheService';

class MyUpload extends React.Component {
  static defaultProps = {
    multiple: false
  };

  constructor(props) {
    super(props);
    this.state = {
      accept: {
        office: ['application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'application/vnd.openxmlformats-officedocument.presentationml.presentation',
        'application/vnd.ms-powerpoint', 'application/msword', 'application/vnd.ms-excel'],
        pdf: ['application/pdf'],
        img: ['image/png', 'image/jpg', 'image/jpeg'],
        text: ['text/plain']
      },
      fileTypeError: {
        nameError: {
          value: '文件名不合法！',
          desc: '文件名不能包含美元符号，逗号，斜杠，反斜杠，请修改后再上传！'
        },
        sizeError: {
          value: '文件大小超过限制！',
          desc: '文件大小不能超过10M！'
        },
        typeError: {
          value: '文件类型错误！',
          desc: '文件类型仅支持静态图片、office(支持doc、docx、xls、xlsx、ppt、pptx)文档、pdf文档和普通文本文档！'
        },
        nameLengthError: {
          value: '文件名错误！',
          desc: '文件名长度不能超过100个字符！'
        }
      },
      stsToken: '',
      client: {},
      fileList: [],
      value: '',
      disabled: false,
      size: '0B',
      status: 'active',
      percent: 0,
      reloadStatus: true
    };
  }

  onRemove = file => {
    const { client } = this.state;
    this.setState({
      size: '0B',
      disabled: false,
      percent: 0,
      status: 'active'
    });
    this.props.onChange && this.props.onChange('');
    return true;
  };

  customRequest = (info, response) => {
    // 开始上传
    const that = this;
    const { stsToken } = this.state;
    const token = response || stsToken;

    if (!token || Object.keys(token).length === 0) {
      info.onError('获取token失败');
    } else {
       /* eslint-disable */
      const client = new OSS.Wrapper({
        region: 'oss-cn-hangzhou',
        accessKeyId: token.accessKeyId,
        accessKeySecret: token.accessKeySecret,
        stsToken: token.securityToken,
        bucket: 'demo-loc'
      });
      const value = token.tenantIdentifier + '/' + info.file.uid + '$' + info.file.name;
      this.setState({
        client,
        value
      });
      client.multipartUpload(value, info.file, {
        progress: function* (p) {
          that.setState({
            percent: ((p === 0 ? p + 0.05 : p) * 100).toFixed(2)
          });
        }
      }).then(result => {
        info.onSuccess(result);
      }).catch(err => {
        if (err.code === 'InvalidSecurityToken' && this.state.reloadStatus) {
          // 重试一次获取token
          that.setState({
            reloadStatus: false
          });
          updateSecurityToken().then(res => {
            this.customRequest(info, res);
          }).catch(error => {
            info.onError(error.msgCode);
          });
        } else {
          info.onError(err.code + '[' + err.requestId + ']');
        }
      });
    }
  };

  onChange = info => {
    if (info.file.status === 'done') {
      this.setState({
        disabled: false,
        status: 'success'
      });
      Modal.success({
        title: '上传成功',
        content: `${info.file.name} 文件上传成功`,
      });
      const value = info.file.name + ',' + this.state.value + ',' + info.file.size;
      this.props.onChange && this.props.onChange(value);
    } else if (info.file.status === 'error') {
      this.showErrorModal(info.file, info.file.error);
    }
  };

  beforeUpload = (file, fileList = []) => {
    const { multiple } = this.props;
    return new Promise((res, rej) => {
      this.setState({
        disabled: true,
        percent: 5,
        status: 'active'
      });
      this.validateFile(file, errors => {
        if (errors.length === 0) {
          if (!multiple) {
            // 不是多选，列表上只能显示一条文件信息，其余的都需要移除
            fileList.forEach(item => {
              // this.onRemove(file)
            });
            this.setState({
              fileList: [file],
              size: this.resolveFileSize(file.size)
            });
          }
          const stsToken = getSecurityToken();
          if (stsToken && Object.keys(stsToken).length > 0) {
            res(this.setState({
              stsToken,
              reloadStatus: true
            }));
          } else {
            updateSecurityToken().then(response => {
              res(this.setState({
                stsToken: response,
                reloadStatus: true
              }));
            }).catch(err => {
              rej(this.showErrorModal(file, err.msgCode || err));
            });
          }
        } else {
          rej(this.showErrorModal(file, errors));
        }
      });
    });
  };

  showErrorModal = (file, err) => {
    this.setState({
      disabled: false,
      status: 'active',
      percent: 0,
      size: '0B',
      fileList: []
    });
    this.props.onChange && this.props.onChange('');
    Modal.error({
      title: '上传失败',
      content: <span>文件 { file.name } 上传失败！ <br /> 失败原因： { err }</span>,
    });
  };

  validateFile = (file, call) => {
    const errors = [];
    const reg = /[,|$]|[/|\\]/g;
    if (reg.test(file.name)) {
      errors.push('nameError');
    }
    if (file.size / 1024 / 1024 > 10) {
      errors.push('sizeError');
    }
    const accepts = Object.keys(this.state.accept).reduce((a, b) => a.concat(this.state.accept[b]), []);
    if (!accepts.includes(file.type)) {
      errors.push('typeError');
    }
    if (file.name.length > 100) {
      errors.push('nameLengthError');
    }
    if (errors.length > 1) {
      call(errors.map(error => <span><br />{ this.state.fileTypeError[error].value }</span>));
    } else {
      call(errors.map(error => <span>{ this.state.fileTypeError[error].value }<br />
        { this.state.fileTypeError[error].desc }<br />
      </span>));
    }
  };

  resolveFileSize = size => {
    let tempSize = '0B';
    if (size >= 0 && size < 1024) {
      tempSize = size + 'B';
    }
    if (size >= 1024 && size < (1024 * 1024)) {
      tempSize = (size / 1024).toFixed(2) + 'K';
    }
    if (size >= (1024 * 1024)) {
      tempSize = (size / (1024 * 1024)).toFixed(2) + 'M';
    }
    return tempSize;
  };

  render() {
    const { multiple } = this.props;
    return (
      <div>
        <div>
          <Upload
            onChange={this.onChange}
            customRequest={this.customRequest}
            onRemove={this.onRemove}
            multiple={multiple}
            fileList={this.state.fileList}
            beforeUpload={this.beforeUpload}
          >
            <Button disabled={this.state.disabled}>
              <Icon type="upload" /> 选择文件
            </Button>
          </Upload>
        </div>
        <div>
          <span>{'文件大小：' + this.state.size }</span><br />
          <Progress percent={this.state.percent} status={this.state.status} />
        </div>
      </div>
    );
  }
}

const compRender = config => {
  const { record = {} } = config;
  return (
    <MyUpload
      multiple={record.multiple || false}
    />
  );
};

export default {
  [VIEW]: staticDisplay,
  [EDIT]: compRender
};
