import { __assign, __spreadArrays } from "tslib";
import React, { useContext, useRef, useState } from 'react';
import classNames from 'classnames';
import { ConfigContext } from '../config-provider/config-context';
import { getPrefixCls } from '../_utils/general';
import ajax from './ajax';
import UploadList from './upload-list';
import DraggerCover from './dragger-cover';
var Upload = function (props) {
    var _a;
    var _b = props.defaultFileList, defaultFileList = _b === void 0 ? [] : _b, _c = props.httpRequest, httpRequest = _c === void 0 ? ajax : _c, _d = props.disabled, disabled = _d === void 0 ? false : _d, _e = props.method, method = _e === void 0 ? 'post' : _e, headers = props.headers, withCredentials = props.withCredentials, accept = props.accept, action = props.action, multiple = props.multiple, name = props.name, data = props.data, drag = props.drag, beforeUpload = props.beforeUpload, limit = props.limit, onExceed = props.onExceed, onProgress = props.onProgress, onSuccess = props.onSuccess, onError = props.onError, onChange = props.onChange, onRemove = props.onRemove, tip = props.tip, className = props.className, style = props.style, children = props.children, customisedCls = props.prefixCls;
    var configContext = useContext(ConfigContext);
    var prefixCls = getPrefixCls('upload', configContext.prefixCls, customisedCls);
    var cls = classNames(prefixCls, className, (_a = {},
        _a[prefixCls + "_disabled"] = disabled,
        _a));
    var fileRef = useRef(null);
    var _f = useState('fileList' in props && Array.isArray(props.fileList) ? props.fileList : defaultFileList), fileList = _f[0], setFileList = _f[1];
    var updateFileList = function (updateFile, targetObj) {
        setFileList(function (prevState) {
            return prevState.map(function (file) {
                if (file.uid === updateFile.uid) {
                    return __assign(__assign({}, file), targetObj);
                }
                else {
                    return file;
                }
            });
        });
    };
    var xhrOnProgress = function (percent, uploadFile) {
        var updateObj = { percent: percent, status: 'uploading' };
        updateFileList(uploadFile, updateObj);
        onProgress && onProgress(percent, __assign(__assign({}, uploadFile), updateObj), fileList);
    };
    var xhrOnComplete = function (e, uploadFile) {
        var updateObj = { status: 'done' };
        updateFileList(uploadFile, updateObj);
        var updatedUploadFile = __assign(__assign({}, uploadFile), updateObj);
        onSuccess && onSuccess(e, updatedUploadFile, fileList);
        onChange && onChange(updatedUploadFile, fileList);
    };
    var xhrOnError = function (e, uploadFile) {
        var updateObj = { status: 'error' };
        updateFileList(uploadFile, { status: 'error' });
        var updatedUploadFile = __assign(__assign({}, uploadFile), updateObj);
        onError && onError(e, updatedUploadFile, fileList);
        onChange && onChange(updatedUploadFile, fileList);
    };
    var postRequest = function (file) {
        var uploadFile = {
            uid: 'file-' + Date.now(),
            name: file.name,
            status: 'ready',
            percent: 0,
        };
        setFileList(function (prevState) { return __spreadArrays([uploadFile], prevState); });
        httpRequest({
            headers: headers,
            withCredentials: withCredentials,
            file: file,
            data: data,
            filename: name || file.name,
            method: method,
            action: action,
            onProgress: function (percent) { return xhrOnProgress(percent, uploadFile); },
            onSuccess: function (e) { return xhrOnComplete(e, uploadFile); },
            onError: function (e) { return xhrOnError(e, uploadFile); },
        });
    };
    var uploadFiles = function (files) {
        if (limit && fileList.length + files.length > limit) {
            onExceed && onExceed(files, fileList);
            return;
        }
        var postFiles = Array.from(files);
        postFiles.forEach(function (file) {
            if (!beforeUpload) {
                postRequest(file);
            }
            else {
                var res = beforeUpload(file);
                if (res && res instanceof Promise) {
                    res.then(function (processedFile) { return postRequest(processedFile); });
                }
                else if (res !== false) {
                    postRequest(file);
                }
            }
        });
    };
    var handleTriggerOnClick = function () {
        if (!disabled) {
            if (fileRef.current) {
                fileRef.current.click();
            }
        }
    };
    var handleFileOnChange = function (e) {
        var files = e.currentTarget.files;
        if (!files) {
            return;
        }
        uploadFiles(files);
        if (fileRef.current) {
            fileRef.current.value = '';
        }
    };
    var handleOnRemove = function (uploadFile) {
        setFileList(function (prevState) { return prevState.filter(function (file) { return file.uid !== uploadFile.uid; }); });
        onRemove && onRemove(uploadFile);
    };
    return (React.createElement(React.Fragment, null,
        React.createElement("div", { className: cls, style: style, onClick: handleTriggerOnClick },
            drag ? (React.createElement(DraggerCover, { prefixCls: prefixCls, onFile: uploadFiles, disabled: disabled }, children)) : (children),
            tip && React.createElement("div", { className: prefixCls + "__tip" }, tip),
            React.createElement("input", { ref: fileRef, accept: accept, multiple: multiple, type: "file", style: { display: 'none' }, onChange: handleFileOnChange })),
        React.createElement(UploadList, { prefixCls: prefixCls, fileList: fileList, onRemove: handleOnRemove })));
};
Upload.displayName = 'Upload';
export default Upload;
//# sourceMappingURL=upload.js.map