import _extends from "@babel/runtime/helpers/esm/extends";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";

/* eslint-disable */
import React, { Component } from 'react';
import Cropper from 'react-cropper';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Close from '../icons/internals/Close';
import Rolling from '../icons/internals/Rolling'; // import Add from '../icons/internals/Add';

import Error from '../icons/internals/Error';
import Folder from '../icons/internals/Folder';
import IconButton from '../button/IconButton';
import Button from '../button/Button';
import Modal from '../modal/Modal';
import Radio from '../radio/Radio';
import RadioGroup from '../radio/RadioGroup';
import Input from '../input/Input';
import attrAccept from './accept';
import 'cropperjs/dist/cropper.css';
var now = Date.now();
var fileId = 0;

function getUid() {
  return "ne-upload-".concat(now, "-").concat(++fileId);
}

var isImage = function isImage(file) {
  return file && file.type.includes('image');
};

var previewFile = function previewFile(file, cb) {
  var reader = new FileReader();
  reader.addEventListener('load', function () {
    file.url = reader.result;
    cb && cb(file.url);
  }, false);

  if (file) {
    reader.readAsDataURL(file);
  }
};

var Upload =
/*#__PURE__*/
function (_Component) {
  _inherits(Upload, _Component);

  _createClass(Upload, null, [{
    key: "getDerivedStateFromProps",
    value: function getDerivedStateFromProps(props, state) {
      var defaultFiles = props.defaultFiles;

      if (!state.isControlled && defaultFiles !== state.prevFiles) {
        return {
          files: defaultFiles,
          prevFiles: defaultFiles
        };
      }

      return null;
    }
  }]);

  function Upload(props) {
    var _this;

    _classCallCheck(this, Upload);

    _this = _possibleConstructorReturn(this, _getPrototypeOf(Upload).call(this));

    _defineProperty(_assertThisInitialized(_this), "handleChange", function (e) {
      var files = e.target.files;

      _this.uploadFiles(files);

      try {
        e.target.value = null;
      } catch (_unused) {
        return e;
      }
    });

    _defineProperty(_assertThisInitialized(_this), "previewImage", function (file) {
      _this.setState({
        previewModal: true,
        currentID: file.uid,
        src: file.url
      });
    });

    _defineProperty(_assertThisInitialized(_this), "cropperImage", function (file) {
      _this.setState({
        showModal: true,
        currentID: file.uid,
        src: file.url
      });
    });

    _defineProperty(_assertThisInitialized(_this), "handleClick", function () {
      var e = _this.fileInput;

      if (!e) {
        return;
      }

      e.click();
    });

    _defineProperty(_assertThisInitialized(_this), "handleKeyDown", function (e) {
      if (e.key === 'Enter') {
        _this.onClick();
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleFileDrop", function (e) {
      e.preventDefault();
      var accept = _this.props.accept;

      if (e.type === 'dragover') {
        return;
      }

      var files = Array.from(e.dataTransfer.files).filter(function (file) {
        return attrAccept(file, accept);
      });

      _this.uploadFiles(files);
    });

    _defineProperty(_assertThisInitialized(_this), "uploadFiles", function (files) {
      var _this$props = _this.props,
          avatar = _this$props.avatar,
          single = _this$props.single;
      Array.from(files).slice(0, avatar || single ? 1 : files.length).forEach(function (file) {
        file.uid = getUid();
        file.loading = true;

        if (isImage(file)) {
          previewFile(file, function (fileUrl) {
            _this.setState({
              src: fileUrl
            });

            return _this.forceUpdate();
          });
        }

        setTimeout(function () {
          _this.upload(file);
        }, 0);
      });
    });

    _defineProperty(_assertThisInitialized(_this), "upload", function (file) {
      var _this$props2 = _this.props,
          beforeUpload = _this$props2.beforeUpload,
          onChange = _this$props2.onChange,
          avatar = _this$props2.avatar,
          single = _this$props2.single,
          files = _this$props2.files;
      var stateFiles = _this.state.files;
      var oldFiles = _this.isControlled ? files : stateFiles;
      var before = beforeUpload ? beforeUpload(file, oldFiles) : file;

      if (!before) {
        return;
      }

      if (!before.then) {
        file.loading = false;
      }

      if (onChange && (_this.isControlled || !before.then)) {
        onChange(avatar || single ? [file] : oldFiles.concat([file]), file);
      }

      if (!_this.isControlled) {
        _this.setState(function (state) {
          return {
            files: avatar || single ? [file] : state.files.concat([file])
          };
        });
      }

      if (before.then) {
        return before.then(function (processedFile) {
          if (!_this.monuted) {
            return;
          }

          var onChange = _this.props.onChange;
          var files = _this.isControlled ? _this.props.files : _this.state.files;
          processedFile.uid = file.uid;
          processedFile.loading = false;

          if (files.find(function (oldFile) {
            return oldFile.uid === file.uid;
          })) {
            if (onChange) {
              var newList = files.map(function (oldFile) {
                return oldFile.uid === file.uid ? processedFile : oldFile;
              });
              onChange(_this.isControlled ? newList : newList.filter(function (file) {
                return file && !file.loading && !file.fail;
              }), processedFile);
            }

            if (!_this.isControlled) {
              _this.setState(function (state) {
                return {
                  files: state.files.map(function (oldFile) {
                    return oldFile.uid === file.uid ? processedFile : oldFile;
                  })
                };
              });
            }
          }
        }).catch(function (processedFile) {
          if (!_this.monuted) {
            return;
          }

          var _this$props3 = _this.props,
              avatar = _this$props3.avatar,
              single = _this$props3.single;
          var files = _this.isControlled ? _this.props.files : _this.state.files;
          processedFile.fail = true;
          processedFile.loading = false;
          processedFile.uid = file.uid;

          if (files.find(function (oldFile) {
            return oldFile.uid === file.uid;
          })) {
            var newList = files.map(function (oldFile) {
              return oldFile.uid === file.uid ? processedFile : oldFile;
            });

            if (onChange && _this.isControlled) {
              onChange(newList, processedFile);
            }

            if (!_this.isControlled) {
              if ((avatar || single) && oldFiles.filter(function (file) {
                return file && !file.loading && !file.fail;
              }).length) {
                onChange([], null);
              }

              _this.setState(function (state) {
                return {
                  files: state.files.map(function (oldFile) {
                    return oldFile.uid === file.uid ? processedFile : oldFile;
                  })
                };
              });
            }
          }
        });
      }
    });

    _defineProperty(_assertThisInitialized(_this), "handleDelete", function (uid) {
      return function () {
        var onChange = _this.props.onChange;
        var files = _this.isControlled ? _this.props.files : _this.state.files;

        if (onChange) {
          if (!_this.isControlled) {
            var target = files.find(function (file) {
              return file && !file.loading && !file.fail && file.uid === uid;
            });

            if (target) {
              onChange(files.filter(function (file) {
                return file !== target && !file.fail && !file.loading;
              }), target);
            }
          } else {
            var _target = files.find(function (file) {
              return file && file.uid === uid;
            });

            onChange(files.filter(function (file) {
              return file !== _target;
            }), _target);
          }
        }

        if (!_this.isControlled) {
          _this.setState(function (state) {
            return {
              files: state.files.filter(function (file) {
                return file.uid !== uid;
              })
            };
          });
        }
      };
    });

    _defineProperty(_assertThisInitialized(_this), "getInput", function (node) {
      _this.fileInput = node;
    });

    _defineProperty(_assertThisInitialized(_this), "itemRender", function (file) {
      var _classNames;

      var _this$props4 = _this.props,
          prefixCls = _this$props4.prefixCls,
          avatar = _this$props4.avatar,
          single = _this$props4.single,
          gallery = _this$props4.gallery,
          accept = _this$props4.accept,
          multiple = _this$props4.multiple,
          disabled = _this$props4.disabled;
      return React.createElement("div", {
        key: file.uid,
        className: classNames("".concat(prefixCls, "-list-item"), (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-list-item-loading"), file.loading), _defineProperty(_classNames, "".concat(prefixCls, "-list-item-fail"), file.fail), _defineProperty(_classNames, "".concat(prefixCls, "-list-item-success"), !file.loading && !file.fail), _defineProperty(_classNames, "".concat(prefixCls, "-list-item-gallery"), gallery), _defineProperty(_classNames, "".concat(prefixCls, "-list-item-single"), avatar || single), _classNames))
      }, !disabled && (avatar || single) ? React.createElement("div", null, React.createElement("div", null, React.createElement("div", {
        className: "".concat(prefixCls, "-cropper-mask"),
        onClick: _this.handleClick
      }, React.createElement("input", {
        type: "file",
        ref: _this.getInput,
        style: {
          display: 'none'
        },
        accept: accept,
        multiple: !(avatar || single) && multiple,
        onChange: _this.handleChange
      }), "\u91CD\u65B0\u4E0A\u4F20"), React.createElement("div", {
        className: "".concat(prefixCls, "-mask"),
        onClick: function onClick() {
          _this.cropperImage(file);
        }
      }, "\u88C1\u526A")), React.createElement("div", {
        className: "".concat(prefixCls, "-preview-btn"),
        onClick: function onClick() {
          _this.previewImage(file);
        }
      }, "\u9884\u89C8")) : null, React.createElement("div", {
        className: "".concat(prefixCls, "-list-item-container")
      }, file.loading ? React.createElement(Rolling, {
        spin: true,
        className: "".concat(prefixCls, "-status")
      }) : file.fail ? React.createElement(Error, {
        className: "".concat(prefixCls, "-status")
      }) : (avatar || single || gallery) && file.url ? React.createElement("img", {
        src: file.url,
        alt: "\u9884\u89C8",
        className: "".concat(prefixCls, "-status ").concat(prefixCls, "-preview")
      }) : React.createElement(Folder, {
        className: "".concat(prefixCls, "-status")
      })), avatar || single ? null : React.createElement("span", {
        className: "".concat(prefixCls, "-file-name")
      }, file.name), React.createElement(IconButton, {
        variant: "text",
        onClick: _this.handleDelete(file.uid),
        className: "".concat(prefixCls, "-delete")
      }, React.createElement(Close, {
        size: "small"
      })));
    });

    _defineProperty(_assertThisInitialized(_this), "cropImage", function (callback) {
      if (typeof _this.cropper.getCroppedCanvas() === 'undefined') {
        return;
      }

      var cropBoxData = _this.cropper.getCropBoxData();

      var canvasData = _this.cropper.getCanvasData();

      var left = cropBoxData.left - canvasData.left;
      var top = cropBoxData.top - canvasData.top;
      var width = cropBoxData.width;
      var height = cropBoxData.height;
      var _this$state = _this.state,
          cropperWidth = _this$state.cropperWidth,
          cropperHeight = _this$state.cropperHeight;

      _this.setState({
        cropResult: _this.cropper.getCroppedCanvas({
          width: cropperWidth,
          height: cropperHeight
        }).toDataURL(),
        left: left,
        top: top,
        width: width,
        height: height
      }, function () {
        if (typeof callback === "function") callback();
      });
    });

    _defineProperty(_assertThisInitialized(_this), "cropImageSure", function () {
      var mine = _assertThisInitialized(_this);

      _this.cropImage(function () {
        var _mine$state = mine.state,
            cropResult = _mine$state.cropResult,
            currentID = _mine$state.currentID;
        var _mine$props = mine.props,
            cropSure = _mine$props.cropSure,
            onChange = _mine$props.onChange,
            radioDefault = _mine$props.radioDefault;
        var files = mine.isControlled ? mine.props.files : mine.state.files;
        mine.setState({
          showModal: false,
          cropperWidth: radioDefault ? parseInt(radioDefault.split('*')[0], 10) : 100,
          cropperHeight: radioDefault ? parseInt(radioDefault.split('*')[1], 10) : 100,
          cropperMode: radioDefault || 'custimage'
        });
        if (cropSure) cropSure(cropResult).then(function (res) {
          if (onChange) {
            files.filter(function (file) {
              if (file.uid == currentID) {
                Object.assign(file, res);
              }
            });
            onChange(files);
          }
        });
      });
    });

    _defineProperty(_assertThisInitialized(_this), "cropImageCancel", function () {
      var radioDefault = _this.props.radioDefault;

      _this.setState({
        showModal: false,
        cropResult: null,
        currentID: '',
        cropperWidth: radioDefault ? parseInt(radioDefault.split('*')[0], 10) : 100,
        cropperHeight: radioDefault ? parseInt(radioDefault.split('*')[1], 10) : 100,
        cropperMode: radioDefault || 'custimage'
      });
    });

    _defineProperty(_assertThisInitialized(_this), "previewImageCancel", function () {
      var radioDefault = _this.props.radioDefault;

      _this.setState({
        previewModal: false
      });
    });

    _defineProperty(_assertThisInitialized(_this), "changeSize", function (value) {
      var radioDefault = _this.props.radioDefault;
      var cropperWidth = radioDefault ? parseInt(radioDefault.split('*')[0], 10) : 100;
      var cropperHeight = radioDefault ? parseInt(radioDefault.split('*')[1], 10) : 100;

      if (value !== 'custimage') {
        cropperWidth = parseInt(value.split('*')[0], 10);
        cropperHeight = parseInt(value.split('*')[1], 10);
      }

      _this.setState({
        cropperMode: value,
        cropperWidth: cropperWidth,
        cropperHeight: cropperHeight
      });
    });

    _defineProperty(_assertThisInitialized(_this), "setCropperSizeWidth", function (e) {
      _this.setState({
        cropperWidth: parseInt(e.target.value || 0, 10)
      });
    });

    _defineProperty(_assertThisInitialized(_this), "setCropperSizeHeight", function (e) {
      _this.setState({
        cropperHeight: parseInt(e.target.value || 0, 10)
      });
    });

    var _files = props.files,
        defaultFiles = props.defaultFiles,
        _radioDefault = props.radioDefault;
    _this.isControlled = _files != null;
    _this.state = {
      isControlled: _this.isControlled,
      files: defaultFiles,
      prevFiles: defaultFiles,
      showModal: false,
      src: '',
      cropResult: null,
      currentID: '',
      cropperWidth: _radioDefault ? parseInt(_radioDefault.split('*')[0], 10) : 100,
      cropperHeight: _radioDefault ? parseInt(_radioDefault.split('*')[1], 10) : 100,
      cropperMode: _radioDefault || 'custimage'
    };
    return _this;
  }

  _createClass(Upload, [{
    key: "componentDidMount",
    value: function componentDidMount() {
      this.monuted = true;
    }
  }, {
    key: "componentWillUnmount",
    value: function componentWillUnmount() {
      this.mounted = false;
    }
  }, {
    key: "render",
    value: function render() {
      var _classNames2,
          _this2 = this;

      var _this$props5 = this.props,
          prefixCls = _this$props5.prefixCls,
          className = _this$props5.className,
          disabled = _this$props5.disabled,
          multiple = _this$props5.multiple,
          accept = _this$props5.accept,
          gallery = _this$props5.gallery,
          avatar = _this$props5.avatar,
          single = _this$props5.single,
          cropperpreview = _this$props5.cropperpreview,
          children = _this$props5.children,
          fileRender = _this$props5.fileRender,
          propsFiles = _this$props5.files,
          radioList = _this$props5.radioList,
          radioDefault = _this$props5.radioDefault;
      var _this$state2 = this.state,
          stateFiles = _this$state2.files,
          showModal = _this$state2.showModal,
          previewModal = _this$state2.previewModal,
          src = _this$state2.src,
          cropResult = _this$state2.cropResult,
          cropperHeight = _this$state2.cropperHeight,
          cropperWidth = _this$state2.cropperWidth,
          cropperMode = _this$state2.cropperMode;
      var files = this.isControlled ? propsFiles : stateFiles;
      var classes = classNames("".concat(prefixCls, "-trigger"), className, (_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_classNames2, "".concat(prefixCls, "-gallery"), gallery), _defineProperty(_classNames2, "".concat(prefixCls, "-single"), avatar || single), _classNames2));
      var listClasses = classNames("".concat(prefixCls, "-list"));
      var events = disabled ? {} : {
        onClick: this.handleClick,
        onKeyDown: this.handleKeyDown,
        onDrop: this.handleFileDrop,
        onDragOver: this.handleFileDrop,
        tabIndex: '0'
      };
      var render = fileRender || this.itemRender;
      var button = React.createElement("div", _extends({}, files.length && (avatar || single) ? {} : events, {
        className: classes
      }), React.createElement("input", {
        type: "file",
        ref: this.getInput,
        style: {
          display: 'none'
        },
        accept: accept,
        multiple: !(avatar || single) && multiple,
        onChange: this.handleChange
      }), children);
      var uploadItem = React.createElement("div", _extends({
        className: classNames("".concat(prefixCls, "-list-item"), "".concat(prefixCls, "-list-item-upload"))
      }, files.length && (avatar || single) ? {} : events), React.createElement("input", {
        type: "file",
        ref: this.getInput,
        style: {
          display: 'none'
        },
        accept: accept,
        multiple: !(avatar || single) && multiple,
        onChange: this.handleChange
      }), children);
      var list = avatar || single ? files.length ? render(files[0], files, this.handleDelete(files[0].uid), events) : uploadItem : React.createElement("div", {
        className: listClasses
      }, files.map(function (file) {
        return render(file, files, _this2.handleDelete(file.uid), events);
      }), gallery ? uploadItem : null);
      return React.createElement("div", null, gallery || avatar || single ? React.createElement("div", {
        className: prefixCls
      }, list) : React.createElement("div", {
        className: prefixCls
      }, button, list), React.createElement(Modal, {
        size: "large",
        animationName: "scale",
        isOpen: showModal,
        onClose: this.cropImageCancel
      }, React.createElement("div", null, React.createElement("div", {
        style: {
          marginBottom: 5
        }
      }, React.createElement(RadioGroup, {
        onChange: function onChange(e, value) {
          return _this2.changeSize(value);
        },
        defaultValue: radioDefault || 'custimage'
      }, radioList, React.createElement(Radio, {
        label: "\u81EA\u5B9A\u4E49",
        value: "custimage",
        key: "custimage"
      })), cropperMode === 'custimage' ? React.createElement("div", null, "width:", React.createElement(Input, {
        size: "small",
        style: {
          marginRight: 5
        },
        placeholder: "width",
        value: cropperWidth,
        onChange: this.setCropperSizeWidth
      }), "height:", React.createElement(Input, {
        size: "small",
        placeholder: "height",
        value: cropperHeight,
        onChange: this.setCropperSizeHeight
      })) : ''), React.createElement("div", null, React.createElement(Cropper, {
        aspectRatio: cropperWidth / cropperHeight,
        style: {
          height: 400
        },
        guides: true,
        dragMode: "move",
        src: src,
        ref: function ref(cropper) {
          _this2.cropper = cropper;
        }
      }), cropperpreview ? React.createElement("div", {
        className: "box",
        style: {
          maxHeight: 400,
          padding: 10
        }
      }, React.createElement("div", {
        style: {
          marginBottom: 10
        }
      }, "\u9884\u89C8"), cropResult ? React.createElement("img", {
        style: {
          maxHeight: 400
        },
        src: cropResult,
        alt: "\u9884\u89C8"
      }) : '') : ''), React.createElement("div", {
        style: {
          marginTop: 10
        }
      }, cropperpreview ? React.createElement(Button, {
        variant: "contained",
        color: "success",
        onClick: this.cropImage,
        style: {
          marginRight: 5
        }
      }, "\u9884\u89C8") : '', React.createElement(Button, {
        variant: "contained",
        color: "success",
        onClick: this.cropImageSure,
        style: {
          marginRight: 5
        }
      }, "\u786E\u5B9A"), React.createElement(Button, {
        variant: "contained",
        color: "secondary",
        onClick: this.cropImageCancel,
        style: {
          marginRight: 5
        }
      }, "\u53D6\u6D88")))), React.createElement(Modal, {
        size: "large",
        animationName: "scale",
        isOpen: previewModal,
        onClose: this.previewImageCancel
      }, src ? React.createElement("img", {
        style: {
          maxHeight: 400
        },
        src: src,
        alt: "\u9884\u89C8"
      }) : ''));
    }
  }]);

  return Upload;
}(Component);

_defineProperty(Upload, "propTypes", {
  style: PropTypes.object,
  prefixCls: PropTypes.string,
  className: PropTypes.string,

  /** 是否多选 */
  multiple: PropTypes.bool,

  /** 是否禁用 */
  disabled: PropTypes.bool,

  /** 接受上传的文件类型 */
  accept: PropTypes.string,
  children: PropTypes.any,
  data: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),

  /** 上传文件之前的钩子，参数为上传的文件，若返回 false 则停止上传。支持返回一个 Promise 对象 */
  beforeUpload: PropTypes.func,

  /** 默认文件（非受控使用) */
  defaultFiles: PropTypes.array,

  /** 文件列表渲染方法 */
  fileRender: PropTypes.func,

  /** 单图模式 */
  avatar: PropTypes.bool,
  radioDefault: PropTypes.string
});

_defineProperty(Upload, "defaultProps", {
  prefixCls: 'ne-upload',
  defaultFiles: []
});

export { Upload as default };