import _defineProperty from 'babel-runtime/helpers/defineProperty';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
var _jsxFileName = 'src/upload/Upload.jsx';
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import Icon from '../icon';
import Button from '../button';
import classNames from 'classnames';
import attrAccept from './accept';

var now = Date.now();
var fileId = 0;

function getUid() {
    return 'ne-upload-' + now + '-' + ++fileId;
}

var Upload = function (_Component) {
    _inherits(Upload, _Component);

    function Upload(props) {
        _classCallCheck(this, Upload);

        var _this = _possibleConstructorReturn(this, (Upload.__proto__ || Object.getPrototypeOf(Upload)).call(this));

        _this.handleChange = function (e) {
            var files = e.target.files;
            _this.uploadFiles(files);
            try {
                e.target.files = null;
            } finally {}
        };

        _this.handleClick = function () {
            var e = _this.fileInput;
            if (!e) {
                return;
            }
            e.click();
        };

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

        _this.handleFileDrop = function (e) {
            e.preventDefault();

            if (e.type === 'dragover') {
                return;
            }
            var files = Array.from(e.dataTransfer.files).filter(function (file) {
                return attrAccept(file, _this.props.accept);
            });
            _this.uploadFiles(files);
        };

        _this.uploadFiles = function (files) {
            Array.from(files).forEach(function (file) {
                file.uid = getUid();
                file.loading = true;
                setTimeout(function () {
                    return _this.upload(file);
                }, 0);
            });
        };

        _this.upload = function (file) {
            var _this$props = _this.props,
                beforeUpload = _this$props.beforeUpload,
                onChange = _this$props.onChange;

            var files = _this.isControlled ? _this.props.files : _this.state.files;
            var before = beforeUpload ? beforeUpload(file, files) : file;
            if (!before) {
                return;
            }
            if (!before.then) {
                file.loading = false;
            }
            if (onChange && (_this.isControlled || !before.then)) {
                onChange(files.concat([file]), file);
            }
            if (!_this.isControlled) {
                _this.setState(function (state) {
                    return {
                        files: 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 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) {
                            _this.setState(function (state) {
                                return {
                                    files: state.files.map(function (oldFile) {
                                        return oldFile.uid === file.uid ? processedFile : oldFile;
                                    })
                                };
                            });
                        }
                    }
                });
            }
        };

        _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;
                            }), 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;
                            })
                        };
                    });
                }
            };
        };

        _this.getInput = function (node) {
            _this.fileInput = node;
        };

        _this.isControlled = props.files != null;
        if (!_this.isControlled) {
            _this.state = {
                files: props.defaultFiles
            };
        }
        return _this;
    }

    _createClass(Upload, [{
        key: 'componentDidMount',
        value: function componentDidMount() {
            this.monuted = true;
        }
    }, {
        key: 'componentWillReceiveProps',
        value: function componentWillReceiveProps(nextProps) {
            if (!this.isControlled && nextProps.defaultFiles !== this.props.defaultFiles) {
                this.setState({
                    files: nextProps.defaultFiles
                });
            }
        }
    }, {
        key: 'componentWillUnmount',
        value: function componentWillUnmount() {
            this.Mounted = false;
        }
    }, {
        key: 'render',
        value: function render() {
            var _classNames,
                _this2 = this;

            var _props = this.props,
                prefixCls = _props.prefixCls,
                className = _props.className,
                disabled = _props.disabled,
                style = _props.style,
                multiple = _props.multiple,
                accept = _props.accept,
                gallery = _props.gallery,
                children = _props.children,
                fileRender = _props.fileRender;

            var files = this.isControlled ? this.props.files : this.state.files;
            var classes = classNames(prefixCls, className, (_classNames = {}, _defineProperty(_classNames, prefixCls + '-disabled', disabled), _defineProperty(_classNames, prefixCls + '-gallery', gallery), _classNames));
            var listClasses = classNames(prefixCls + '-list', _defineProperty({}, prefixCls + '-list-gallery', gallery));
            var events = disabled ? {} : {
                onClick: this.handleClick,
                onKeyDown: this.onKeyDown,
                onDrop: this.handleFileDrop,
                onDragOver: this.handleFileDrop,
                tabIndex: '0'
            };
            var button = React.createElement(
                'div',
                Object.assign({}, events, { className: classes, role: 'button', style: style, __source: {
                        fileName: _jsxFileName,
                        lineNumber: 231
                    },
                    __self: this
                }),
                React.createElement('input', {
                    type: 'file',
                    ref: this.getInput,
                    style: { display: 'none' },
                    accept: accept,
                    multiple: multiple,
                    onChange: this.handleChange,
                    __source: {
                        fileName: _jsxFileName,
                        lineNumber: 232
                    },
                    __self: this
                }),
                children
            );
            var list = React.createElement(
                'div',
                { className: listClasses, __source: {
                        fileName: _jsxFileName,
                        lineNumber: 244
                    },
                    __self: this
                },
                files.map(function (file) {
                    var _classNames3;

                    return fileRender ? fileRender(file, files) : React.createElement(
                        'div',
                        {
                            key: file.uid,
                            className: classNames(prefixCls + '-list-item', (_classNames3 = {}, _defineProperty(_classNames3, prefixCls + '-list-item-loading', file.loading), _defineProperty(_classNames3, prefixCls + '-list-item-fail', file.fail), _defineProperty(_classNames3, prefixCls + '-list-item-success', !file.loading && !file.fail), _classNames3)), __source: {
                                fileName: _jsxFileName,
                                lineNumber: 250
                            },
                            __self: _this2
                        },
                        file.loading ? React.createElement(Icon, { type: 'spin3', className: prefixCls + '-status', __source: {
                                fileName: _jsxFileName,
                                lineNumber: 258
                            },
                            __self: _this2
                        }) : file.fail ? React.createElement(Icon, { type: 'cancel-o', className: prefixCls + '-status', __source: {
                                fileName: _jsxFileName,
                                lineNumber: 260
                            },
                            __self: _this2
                        }) : React.createElement(Icon, { type: 'file', className: prefixCls + '-status', __source: {
                                fileName: _jsxFileName,
                                lineNumber: 262
                            },
                            __self: _this2
                        }),
                        React.createElement(
                            'span',
                            { className: prefixCls + '-file-name', __source: {
                                    fileName: _jsxFileName,
                                    lineNumber: 264
                                },
                                __self: _this2
                            },
                            file.name
                        ),
                        React.createElement(
                            Button,
                            {
                                shape: 'none',
                                onClick: _this2.handleDelete(file.uid),
                                className: prefixCls + '-delete', __source: {
                                    fileName: _jsxFileName,
                                    lineNumber: 265
                                },
                                __self: _this2
                            },
                            React.createElement(Icon, { type: 'cancel', onClick: _this2.handleDelete(file.uid), __source: {
                                    fileName: _jsxFileName,
                                    lineNumber: 269
                                },
                                __self: _this2
                            })
                        )
                    );
                })
            );
            return gallery ? React.createElement(
                Fragment,
                {
                    __source: {
                        fileName: _jsxFileName,
                        lineNumber: 277
                    },
                    __self: this
                },
                list,
                button
            ) : React.createElement(
                Fragment,
                {
                    __source: {
                        fileName: _jsxFileName,
                        lineNumber: 282
                    },
                    __self: this
                },
                button,
                list
            );
        }
    }]);

    return Upload;
}(Component);

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
};
Upload.defaultProps = {
    prefixCls: 'ne-upload',
    defaultFiles: []
};
export default Upload;