import React, { ReactNode, CSSProperties, RefObject, ChangeEvent, DragEvent } from 'react';
import PropTypes from 'prop-types';
import UploadFoundation from '@douyinfe/semi-foundation/lib/es/upload/foundation';
import FileCard from './fileCard';
import BaseComponent from '../_base/baseComponent';
import Cropper from '../cropper';
import { type ModalReactProps } from '../modal';
import type { FileItem, RenderFileItemProps, UploadListType, PromptPositionType, BeforeUploadProps, AfterUploadProps, OnChangeProps, customRequestArgs, CustomError, RenderPictureCloseProps, RenderFileListTitleProps, CropProps } from './interface';
import { Locale } from '../locale/interface';
import '@douyinfe/semi-foundation/lib/es/upload/upload.css';
import type { CustomFile, UploadAdapter, BeforeUploadObjectResult, AfterUploadResult, FileItemStatus } from '@douyinfe/semi-foundation/lib/es/upload/foundation';
import type { ValidateStatus } from '../_base/baseComponent';
import { ShowTooltip } from '../typography';
export type { FileItem, FileItemStatus, RenderFileItemProps, UploadListType, PromptPositionType, BeforeUploadProps, AfterUploadProps, OnChangeProps, customRequestArgs, CustomError, BeforeUploadObjectResult, AfterUploadResult, RenderFileListTitleProps, CropProps, };
export interface UploadProps {
    accept?: string;
    action: string;
    afterUpload?: (object: AfterUploadProps) => AfterUploadResult;
    beforeUpload?: (object: BeforeUploadProps) => BeforeUploadObjectResult | Promise<BeforeUploadObjectResult> | boolean;
    beforeClear?: (fileList: Array<FileItem>) => boolean | Promise<boolean>;
    beforeRemove?: (file: FileItem, fileList: Array<FileItem>) => boolean | Promise<boolean>;
    capture?: boolean | 'user' | 'environment' | undefined;
    children?: ReactNode;
    className?: string;
    customRequest?: (object: customRequestArgs) => void;
    data?: Record<string, any> | ((file: File) => Record<string, unknown>);
    defaultFileList?: Array<FileItem>;
    directory?: boolean;
    disabled?: boolean;
    dragIcon?: ReactNode;
    dragMainText?: ReactNode;
    dragSubText?: ReactNode;
    draggable?: boolean;
    addOnPasting?: boolean;
    fileList?: Array<FileItem>;
    fileName?: string;
    headers?: Record<string, any> | ((file: File) => Record<string, string>);
    hotSpotLocation?: 'start' | 'end';
    itemStyle?: CSSProperties;
    limit?: number;
    listType?: UploadListType;
    maxSize?: number;
    minSize?: number;
    multiple?: boolean;
    name?: string;
    onAcceptInvalid?: (files: File[]) => void;
    onChange?: (object: OnChangeProps) => void;
    onClear?: () => void;
    onDrop?: (e: Event, files: Array<File>, fileList: Array<FileItem>) => void;
    onError?: (e: CustomError, file: CustomFile, fileList: Array<FileItem>, xhr: XMLHttpRequest) => void;
    onPastingError?: (error: Error | PermissionStatus) => void;
    onExceed?: (fileList: Array<File>) => void;
    onFileChange?: (files: Array<File>) => void;
    onOpenFileDialog?: () => void;
    onPreviewClick?: (fileItem: FileItem) => void;
    onProgress?: (percent: number, file: CustomFile, fileList: Array<FileItem>) => void;
    onRemove?: (currentFile: CustomFile, fileList: Array<FileItem>, currentFileItem: FileItem) => void;
    onRetry?: (fileItem: FileItem) => void;
    onSizeError?: (file: CustomFile, fileList: Array<FileItem>) => void;
    onSuccess?: (responseBody: any, file: CustomFile, fileList: Array<FileItem>) => void;
    previewFile?: (renderFileItemProps: RenderFileItemProps) => ReactNode;
    prompt?: ReactNode;
    promptPosition?: PromptPositionType;
    picHeight?: string | number;
    picWidth?: string | number;
    renderFileItem?: (renderFileItemProps: RenderFileItemProps) => ReactNode;
    renderPicInfo?: (renderFileItemProps: RenderFileItemProps) => ReactNode;
    renderThumbnail?: (renderFileItemProps: RenderFileItemProps) => ReactNode;
    renderPicPreviewIcon?: (renderFileItemProps: RenderFileItemProps) => ReactNode;
    renderPicClose?: (renderPicCloseProps: RenderPictureCloseProps) => ReactNode;
    renderFileOperation?: (fileItem: RenderFileItemProps) => ReactNode;
    fileListTitle?: ReactNode | ((props: RenderFileListTitleProps) => ReactNode);
    showClear?: boolean;
    showPicInfo?: boolean;
    showReplace?: boolean;
    showRetry?: boolean;
    showUploadList?: boolean;
    style?: CSSProperties;
    timeout?: number;
    transformFile?: (file: File) => FileItem;
    uploadTrigger?: 'auto' | 'custom';
    validateMessage?: ReactNode;
    validateStatus?: ValidateStatus;
    withCredentials?: boolean;
    showTooltip?: boolean | ShowTooltip;
    /**
     * Enable image cropping. Pass `true` to use defaults, or a `CropProps` object
     * to customize aspect ratio, shape, output quality, etc.
     */
    crop?: boolean | CropProps;
    /**
     * Callback invoked before opening the crop modal for each image.
     * Return `false` (or resolve to `false`) to skip cropping and upload directly.
     */
    beforeCrop?: (file: File, fileList: File[]) => boolean | Promise<boolean>;
    /** Callback invoked when cropping fails. */
    onCropError?: (error: Error) => void;
    /** Extra props forwarded to the underlying crop Modal. */
    cropModalProps?: ModalReactProps;
}
export interface UploadState {
    dragAreaStatus: 'default' | 'legal' | 'illegal';
    fileList: Array<FileItem>;
    inputKey: number;
    localUrls: Array<string>;
    replaceIdx: number;
    replaceInputKey: number;
    cropperVisible: boolean;
    /** The image file currently being cropped */
    cropperFile: File | null;
    /** Object URL for the image currently being cropped */
    cropperSrc: string;
    /** Remaining image files queued for cropping (cropped one at a time) */
    pendingImageFiles: File[];
    /** Non-image files that bypass cropping but are uploaded together */
    nonImageFiles: File[];
    /** Image files already cropped, accumulated until the queue drains */
    croppedFiles: File[];
    /** Flag to indicate this round was triggered by a replace action */
    isReplaceOperation: boolean;
}
declare class Upload extends BaseComponent<UploadProps, UploadState> {
    static propTypes: {
        accept: PropTypes.Requireable<string>;
        action: PropTypes.Validator<string>;
        addOnPasting: PropTypes.Requireable<boolean>;
        afterUpload: PropTypes.Requireable<(...args: any[]) => any>;
        beforeClear: PropTypes.Requireable<(...args: any[]) => any>;
        beforeRemove: PropTypes.Requireable<(...args: any[]) => any>;
        beforeUpload: PropTypes.Requireable<(...args: any[]) => any>;
        children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
        className: PropTypes.Requireable<string>;
        customRequest: PropTypes.Requireable<(...args: any[]) => any>;
        data: PropTypes.Requireable<object>;
        defaultFileList: PropTypes.Requireable<any[]>;
        directory: PropTypes.Requireable<boolean>;
        disabled: PropTypes.Requireable<boolean>;
        dragIcon: PropTypes.Requireable<PropTypes.ReactNodeLike>;
        dragMainText: PropTypes.Requireable<PropTypes.ReactNodeLike>;
        dragSubText: PropTypes.Requireable<PropTypes.ReactNodeLike>;
        draggable: PropTypes.Requireable<boolean>;
        fileList: PropTypes.Requireable<any[]>;
        fileName: PropTypes.Requireable<string>;
        headers: PropTypes.Requireable<object>;
        hotSpotLocation: PropTypes.Requireable<string>;
        itemStyle: PropTypes.Requireable<object>;
        limit: PropTypes.Requireable<number>;
        listType: PropTypes.Requireable<"none" | "picture" | "list">;
        maxSize: PropTypes.Requireable<number>;
        minSize: PropTypes.Requireable<number>;
        multiple: PropTypes.Requireable<boolean>;
        name: PropTypes.Requireable<string>;
        onAcceptInvalid: PropTypes.Requireable<(...args: any[]) => any>;
        onChange: PropTypes.Requireable<(...args: any[]) => any>;
        onClear: PropTypes.Requireable<(...args: any[]) => any>;
        onDrop: PropTypes.Requireable<(...args: any[]) => any>;
        onError: PropTypes.Requireable<(...args: any[]) => any>;
        onExceed: PropTypes.Requireable<(...args: any[]) => any>;
        onFileChange: PropTypes.Requireable<(...args: any[]) => any>;
        onOpenFileDialog: PropTypes.Requireable<(...args: any[]) => any>;
        onPreviewClick: PropTypes.Requireable<(...args: any[]) => any>;
        onProgress: PropTypes.Requireable<(...args: any[]) => any>;
        onRemove: PropTypes.Requireable<(...args: any[]) => any>;
        onRetry: PropTypes.Requireable<(...args: any[]) => any>;
        onSizeError: PropTypes.Requireable<(...args: any[]) => any>;
        onSuccess: PropTypes.Requireable<(...args: any[]) => any>;
        onPastingError: PropTypes.Requireable<(...args: any[]) => any>;
        previewFile: PropTypes.Requireable<(...args: any[]) => any>;
        prompt: PropTypes.Requireable<PropTypes.ReactNodeLike>;
        promptPosition: PropTypes.Requireable<"left" | "right" | "bottom">;
        picWidth: PropTypes.Requireable<NonNullable<string | number>>;
        picHeight: PropTypes.Requireable<NonNullable<string | number>>;
        renderFileItem: PropTypes.Requireable<(...args: any[]) => any>;
        renderPicPreviewIcon: PropTypes.Requireable<(...args: any[]) => any>;
        renderFileOperation: PropTypes.Requireable<(...args: any[]) => any>;
        renderPicClose: PropTypes.Requireable<(...args: any[]) => any>;
        renderPicInfo: PropTypes.Requireable<(...args: any[]) => any>;
        renderThumbnail: PropTypes.Requireable<(...args: any[]) => any>;
        fileListTitle: PropTypes.Requireable<NonNullable<PropTypes.ReactNodeLike | ((...args: any[]) => any)>>;
        showClear: PropTypes.Requireable<boolean>;
        showPicInfo: PropTypes.Requireable<boolean>;
        showReplace: PropTypes.Requireable<boolean>;
        showRetry: PropTypes.Requireable<boolean>;
        showUploadList: PropTypes.Requireable<boolean>;
        style: PropTypes.Requireable<object>;
        timeout: PropTypes.Requireable<number>;
        transformFile: PropTypes.Requireable<(...args: any[]) => any>;
        uploadTrigger: PropTypes.Requireable<"auto" | "custom">;
        validateMessage: PropTypes.Requireable<PropTypes.ReactNodeLike>;
        validateStatus: PropTypes.Requireable<"default" | "error" | "warning" | "success">;
        withCredentials: PropTypes.Requireable<boolean>;
        showTooltip: PropTypes.Requireable<NonNullable<boolean | object>>;
        crop: PropTypes.Requireable<NonNullable<boolean | object>>;
        beforeCrop: PropTypes.Requireable<(...args: any[]) => any>;
        onCropError: PropTypes.Requireable<(...args: any[]) => any>;
        cropModalProps: PropTypes.Requireable<object>;
    };
    static defaultProps: Partial<UploadProps>;
    static FileCard: typeof FileCard;
    constructor(props: UploadProps);
    /**
     * Notes:
     *   The input parameter and return value here do not declare the type, otherwise tsc may report an error in form/fields.tsx when wrap after withField
     *   `The types of the parameters "props" and "nextProps" are incompatible.
           The attribute "action" is missing in the type "Readonly<any>", but it is required in the type "UploadProps".`
     *   which seems to be a bug, remove props type declare here
     */
    static getDerivedStateFromProps(props: any): {
        fileList: any;
    };
    get adapter(): UploadAdapter<UploadProps, UploadState>;
    foundation: UploadFoundation;
    inputRef: RefObject<HTMLInputElement>;
    replaceInputRef: RefObject<HTMLInputElement>;
    cropperRef: RefObject<Cropper>;
    pastingCb: null | ((params: any) => void);
    pasteEventCb: null | ((params: any) => void);
    componentDidMount(): void;
    componentWillUnmount(): void;
    onClick: () => void;
    onChange: (e: ChangeEvent<HTMLInputElement>) => void;
    /**
     * Check if file is an image
     */
    isImageFile: (file: File) => boolean;
    /**
     * Entry point that decides whether incoming files need cropping.
     * Image files are queued for sequential cropping; non-image files are kept aside
     * and uploaded together with the cropped results once the queue drains.
     */
    handleCropFiles: (files: File[], isReplaceOperation?: boolean) => Promise<void>;
    /**
     * Run the user-provided beforeCrop hook (if any) and return whether cropping should proceed.
     * Errors fall back to skipping cropping so users are never blocked.
     */
    shouldCropFile: (file: File, files: File[]) => Promise<boolean>;
    /**
     * Forward files to the appropriate foundation handler based on operation type.
     */
    dispatchUpload: (files: File[], isReplaceOperation: boolean) => void;
    /**
     * Confirm the current crop. If more images are queued, advance to the next one;
     * otherwise dispatch the accumulated cropped files together with any non-image files.
     */
    handleCropOk: () => Promise<void>;
    /**
     * Cancel the current crop session, revoke object URLs and reset state.
     */
    handleCropCancel: () => void;
    /** Internal helper that tears down crop state and resets the file input. */
    closeCropperAndReset: () => void;
    replace: (index: number) => void;
    onReplaceChange: (e: ChangeEvent<HTMLInputElement>) => void;
    clear: () => void;
    remove: (fileItem: FileItem) => void;
    /**
     * ref method
     * insert files at index
     * @param files Array<CustomFile>
     * @param index number
     * @returns
     */
    insert: (files: Array<CustomFile>, index?: number) => void;
    /**
     * ref method
     * manual upload by user
     */
    upload: () => void;
    /**
     * ref method
     * manual open file select dialog
     */
    openFileDialog: () => void;
    renderFile: (file: FileItem, index: number, locale: Locale['Upload']) => ReactNode;
    renderFileList: () => ReactNode;
    renderFileListPic: () => React.JSX.Element;
    renderFileListDefault: () => React.JSX.Element;
    onDrop: (e: DragEvent<HTMLDivElement>) => void;
    onDragOver: (e: DragEvent<HTMLDivElement>) => void;
    onDragLeave: (e: DragEvent<HTMLDivElement>) => void;
    onDragEnter: (e: DragEvent<HTMLDivElement>) => void;
    renderAddContent: () => string | number | boolean | Iterable<React.ReactNode> | React.JSX.Element;
    renderDragArea: () => ReactNode;
    renderCropperModal: () => ReactNode;
    render(): ReactNode;
}
export default Upload;
