import { __assign, __extends, __spreadArray } from "tslib";
import { FILE_UPLOAD_STATUS } from '../constants';
import { patchUploadItemId } from '../utils/id';
import { wrapPromise } from '../utils/wrap-promise';
import AbstractUpload from './AbstractUpload';
var AbstractMultiUpload = (function (_super) {
    __extends(AbstractMultiUpload, _super);
    function AbstractMultiUpload(props) {
        var _this = _super.call(this, props) || this;
        _this.updateFileList = function (list, detail, cb) {
            var updateCallback = function () {
                _this.props.onChange(list, detail);
                cb && cb();
            };
            if (_this.isControlled) {
                updateCallback();
            }
            else {
                _this.setState({
                    fileList: list,
                }, updateCallback);
            }
        };
        _this.deleteUploadItem = function (deleteItem) {
            var innerFileList = _this.fileList;
            var newFileList = innerFileList.filter(function (item) { return item.id !== deleteItem.id; });
            _this.updateFileList(newFileList, {
                item: deleteItem,
                type: 'delete',
            });
        };
        _this.retryUploadItem = function (retryItem) {
            var innerFileList = _this.fileList;
            var newRetryItem = __assign(__assign({}, retryItem), { status: FILE_UPLOAD_STATUS.uploading, percent: 0 });
            var newFileList = innerFileList.map(function (item) {
                return item.id === retryItem.id ? newRetryItem : item;
            });
            _this.updateFileList(newFileList, {
                item: newRetryItem,
                type: 'retry',
            }, function () { return _this.emitOnUpload(retryItem.file, newRetryItem); });
        };
        _this.updateUploadItem = function (updateItemId, overrideProps) {
            var updateItem = _this.getUploadItem(updateItemId);
            if (!updateItem) {
                return;
            }
            var newItem = __assign(__assign({}, updateItem), overrideProps);
            var newFileList = _this.fileList.map(function (item) {
                return item.id === updateItem.id ? newItem : item;
            });
            _this.updateFileList(newFileList, {
                item: newItem,
                type: 'change',
            });
        };
        _this.onTriggerUploadFile = function (file) {
            var beforeUpload = _this.props.beforeUpload;
            var beforeUploadRes = wrapPromise(beforeUpload ? beforeUpload(file) : true);
            return beforeUploadRes
                .then(function () {
                return _this.createNewUploadFileItem(file);
            })
                .then(function (newUploadFileItem) {
                var fileList = _this.state.fileList;
                var innerFileList = fileList;
                var newFileList = __spreadArray(__spreadArray([], innerFileList), [
                    newUploadFileItem,
                ]);
                _this.updateFileList(newFileList, {
                    item: newUploadFileItem,
                    type: 'add',
                }, function () { return _this.emitOnUpload(file, newUploadFileItem); });
            });
        };
        var fileList = props.fileList, defaultFileList = props.defaultFileList;
        if (fileList && defaultFileList) {
            throw new Error("'fileList' can't be used with 'defaultFileList', 'defaultFileList' can only used in uncontrolled component");
        }
        if (fileList) {
            fileList.forEach(patchUploadItemId);
        }
        if (defaultFileList) {
            defaultFileList.forEach(patchUploadItemId);
        }
        _this.state = {
            fileList: defaultFileList || [],
        };
        return _this;
    }
    AbstractMultiUpload.getDerivedStateFromProps = function (nextProps) {
        if ('fileList' in nextProps) {
            return {
                fileList: nextProps.fileList || [],
            };
        }
        return null;
    };
    Object.defineProperty(AbstractMultiUpload.prototype, "isControlled", {
        get: function () {
            return !!this.props.fileList;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AbstractMultiUpload.prototype, "fileList", {
        get: function () {
            return this.isControlled
                ? this.props.fileList
                : this.state.fileList;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AbstractMultiUpload.prototype, "remainAmount", {
        get: function () {
            var maxAmount = this.props.maxAmount;
            return maxAmount - this.fileList.length;
        },
        enumerable: false,
        configurable: true
    });
    AbstractMultiUpload.prototype.getUploadItem = function (id) {
        return this.fileList.find(function (item) { return item.id === id; }) || null;
    };
    return AbstractMultiUpload;
}(AbstractUpload));
export default AbstractMultiUpload;
