function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
        var info = gen[key](arg);
        var value = info.value;
    } catch (error) {
        reject(error);
        return;
    }
    if (info.done) {
        resolve(value);
    } else {
        Promise.resolve(value).then(_next, _throw);
    }
}
function _async_to_generator(fn) {
    return function() {
        var self = this, args = arguments;
        return new Promise(function(resolve, reject) {
            var gen = fn.apply(self, args);
            function _next(value) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
            }
            function _throw(err) {
                asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
            }
            _next(undefined);
        });
    };
}
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
function _instanceof(left, right) {
    if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
        return !!right[Symbol.hasInstance](left);
    } else {
        return left instanceof right;
    }
}
function _object_spread(target) {
    for(var i = 1; i < arguments.length; i++){
        var source = arguments[i] != null ? arguments[i] : {};
        var ownKeys = Object.keys(source);
        if (typeof Object.getOwnPropertySymbols === "function") {
            ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
                return Object.getOwnPropertyDescriptor(source, sym).enumerable;
            }));
        }
        ownKeys.forEach(function(key) {
            _define_property(target, key, source[key]);
        });
    }
    return target;
}
function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object);
    if (Object.getOwnPropertySymbols) {
        var symbols = Object.getOwnPropertySymbols(object);
        if (enumerableOnly) {
            symbols = symbols.filter(function(sym) {
                return Object.getOwnPropertyDescriptor(object, sym).enumerable;
            });
        }
        keys.push.apply(keys, symbols);
    }
    return keys;
}
function _object_spread_props(target, source) {
    source = source != null ? source : {};
    if (Object.getOwnPropertyDescriptors) {
        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
    } else {
        ownKeys(Object(source)).forEach(function(key) {
            Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
        });
    }
    return target;
}
function _ts_generator(thisArg, body) {
    var f, y, t, _ = {
        label: 0,
        sent: function() {
            if (t[0] & 1) throw t[1];
            return t[1];
        },
        trys: [],
        ops: []
    }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
    return d(g, "next", {
        value: verb(0)
    }), d(g, "throw", {
        value: verb(1)
    }), d(g, "return", {
        value: verb(2)
    }), typeof Symbol === "function" && d(g, Symbol.iterator, {
        value: function() {
            return this;
        }
    }), g;
    function verb(n) {
        return function(v) {
            return step([
                n,
                v
            ]);
        };
    }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while(g && (g = 0, op[0] && (_ = 0)), _)try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [
                op[0] & 2,
                t.value
            ];
            switch(op[0]){
                case 0:
                case 1:
                    t = op;
                    break;
                case 4:
                    _.label++;
                    return {
                        value: op[1],
                        done: false
                    };
                case 5:
                    _.label++;
                    y = op[1];
                    op = [
                        0
                    ];
                    continue;
                case 7:
                    op = _.ops.pop();
                    _.trys.pop();
                    continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
                        _ = 0;
                        continue;
                    }
                    if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
                        _.label = op[1];
                        break;
                    }
                    if (op[0] === 6 && _.label < t[1]) {
                        _.label = t[1];
                        t = op;
                        break;
                    }
                    if (t && _.label < t[2]) {
                        _.label = t[2];
                        _.ops.push(op);
                        break;
                    }
                    if (t[2]) _.ops.pop();
                    _.trys.pop();
                    continue;
            }
            op = body.call(thisArg, _);
        } catch (e) {
            op = [
                6,
                e
            ];
            y = 0;
        } finally{
            f = t = 0;
        }
        if (op[0] & 5) throw op[1];
        return {
            value: op[0] ? op[1] : void 0,
            done: true
        };
    }
}
import { Paperclip } from "@sofa-design/icons";
import { ConfigProvider } from "antd";
import classNames from "clsx";
import React, { useContext } from "react";
import AttachmentButtonPopover, { SupportedFileFormats } from "./AttachmentButtonPopover";
import { useStyle } from "./style";
import { isImageFile } from "./utils";
export * from "./AttachmentButtonPopover";
var WAIT_TIME_MS = 16;
var DEFAULT_MESSAGES = {
    uploading: 'Uploading...',
    uploadSuccess: 'Upload success',
    uploadFailed: 'Upload failed',
    maxFileCountExceeded: function maxFileCountExceeded(count) {
        return "最多只能上传 ".concat(count, " 个文件");
    },
    minFileCountRequired: function minFileCountRequired(count) {
        return "至少需要上传 ".concat(count, " 个文件");
    },
    fileSizeExceeded: function fileSizeExceeded(size) {
        return "超过 ".concat(size, " KB");
    }
};
var waitTime = function waitTime(ms) {
    return new Promise(function(resolve) {
        return setTimeout(resolve, ms);
    });
};
var generateFileUUID = function generateFileUUID(fileName) {
    return Date.now() + Math.random() * 1000 + fileName;
};
var prepareFile = function prepareFile(file) {
    file.status = 'uploading';
    file.uuid = generateFileUUID(file.name);
    if (isImageFile(file)) {
        file.previewUrl = URL.createObjectURL(file);
    }
};
var getLocaleMessage = function getLocaleMessage(locale, key, defaultMsg) {
    return (locale === null || locale === void 0 ? void 0 : locale[key]) || defaultMsg;
};
var validateFileSize = function validateFileSize(file, props) {
    if (!props.maxFileSize || file.size <= props.maxFileSize) return true;
    return false;
};
var updateFileMap = function updateFileMap(map, file, onFileMapChange) {
    if (file.uuid) {
        map.set(file.uuid, file);
        onFileMapChange === null || onFileMapChange === void 0 ? void 0 : onFileMapChange(map);
    }
};
var uploadSingleFile = function uploadSingleFile(file, index, props) {
    return _async_to_generator(function() {
        var result, url;
        return _ts_generator(this, function(_state) {
            switch(_state.label){
                case 0:
                    if (!props.uploadWithResponse) return [
                        3,
                        2
                    ];
                    return [
                        4,
                        props.uploadWithResponse(file, index)
                    ];
                case 1:
                    result = _state.sent();
                    file.uploadResponse = result;
                    return [
                        2,
                        {
                            url: result.fileUrl,
                            isSuccess: result.uploadStatus === 'SUCCESS',
                            errorMsg: result.errorMessage || null
                        }
                    ];
                case 2:
                    if (!props.upload) return [
                        3,
                        4
                    ];
                    return [
                        4,
                        props.upload(file, index)
                    ];
                case 3:
                    url = _state.sent();
                    return [
                        2,
                        {
                            url: url,
                            isSuccess: !!url,
                            errorMsg: null
                        }
                    ];
                case 4:
                    return [
                        2,
                        {
                            url: file.previewUrl,
                            isSuccess: !!file.previewUrl,
                            errorMsg: null
                        }
                    ];
            }
        });
    })();
};
var handleUploadSuccess = function handleUploadSuccess(file, url, map, props) {
    file.status = 'done';
    file.url = url;
    updateFileMap(map, file, props.onFileMapChange);
};
var handleUploadError = function handleUploadError(file, errorMsg, map, props, rawError) {
    var _props_onUploadError;
    if (props.removeFileOnUploadError) {
        var _props_onFileMapChange;
        if (file.uuid) map.delete(file.uuid);
        (_props_onFileMapChange = props.onFileMapChange) === null || _props_onFileMapChange === void 0 ? void 0 : _props_onFileMapChange.call(props, map);
    } else {
        file.status = 'error';
        if (errorMsg !== null) file.errorMessage = errorMsg;
        updateFileMap(map, file, props.onFileMapChange);
    }
    (_props_onUploadError = props.onUploadError) === null || _props_onUploadError === void 0 ? void 0 : _props_onUploadError.call(props, {
        file: file,
        error: rawError !== null && rawError !== void 0 ? rawError : errorMsg
    });
};
var processFile = function processFile(file, index, map, props) {
    return _async_to_generator(function() {
        var _props_onExceedMaxSize, maxSizeKb, raw, _ref, url, isSuccess, errorMsg, error, errorMessage;
        return _ts_generator(this, function(_state) {
            switch(_state.label){
                case 0:
                    return [
                        4,
                        waitTime(WAIT_TIME_MS)
                    ];
                case 1:
                    _state.sent();
                    if (!validateFileSize(file, props)) {
                        ;
                        maxSizeKb = Math.round((props.maxFileSize || 0) / 1024);
                        raw = getLocaleMessage(props.locale, 'markdownInput.fileSizeExceeded', DEFAULT_MESSAGES.fileSizeExceeded(maxSizeKb));
                        file.errorMessage = raw.includes('${maxSize}') ? raw.replace(/\$\{maxSize\}/g, String(maxSizeKb)) : raw;
                        file.errorCode = 'FILE_SIZE_EXCEEDED';
                        file.status = 'error';
                        updateFileMap(map, file, props.onFileMapChange);
                        (_props_onExceedMaxSize = props.onExceedMaxSize) === null || _props_onExceedMaxSize === void 0 ? void 0 : _props_onExceedMaxSize.call(props, {
                            file: file,
                            maxSize: props.maxFileSize || 0
                        });
                        return [
                            2
                        ];
                    }
                    _state.label = 2;
                case 2:
                    _state.trys.push([
                        2,
                        4,
                        ,
                        5
                    ]);
                    return [
                        4,
                        uploadSingleFile(file, index, props)
                    ];
                case 3:
                    _ref = _state.sent(), url = _ref.url, isSuccess = _ref.isSuccess, errorMsg = _ref.errorMsg;
                    if (isSuccess && url) {
                        handleUploadSuccess(file, url, map, props);
                    } else {
                        handleUploadError(file, errorMsg, map, props);
                    }
                    return [
                        3,
                        5
                    ];
                case 4:
                    error = _state.sent();
                    errorMessage = _instanceof(error, Error) ? error.message : getLocaleMessage(props.locale, 'uploadFailed', DEFAULT_MESSAGES.uploadFailed);
                    handleUploadError(file, errorMessage, map, props, error);
                    return [
                        3,
                        5
                    ];
                case 5:
                    return [
                        2
                    ];
            }
        });
    })();
};
/**
 * 上传文件到服务器
 *
 * @param files - 要上传的文件列表
 * @param props - 上传配置项
 * @param props.upload - 上传函数，返回文件 URL
 * @param props.uploadWithResponse - 上传函数（返回完整响应）
 * @param props.fileMap - 文件映射表
 * @param props.onFileMapChange - 文件映射变更回调
 * @param props.maxFileSize - 单文件最大大小（字节）
 * @param props.maxFileCount - 最大文件数量
 * @param props.minFileCount - 最小文件数量
 * @param props.locale - 国际化文案
 */ export var upLoadFileToServer = function upLoadFileToServer(files, props) {
    return _async_to_generator(function() {
        var map, existingFileCount, notifyChange, hideLoading, fileList, totalCount, isMaxExceeded, isMinNotMet, propsWithNotify, _props_onExceedMaxCount, maxCount, rawMessage, errorMessage, i, error;
        return _ts_generator(this, function(_state) {
            switch(_state.label){
                case 0:
                    map = props.fileMap || new Map();
                    existingFileCount = map.size;
                    // Always notify with a new Map reference so React state setters always trigger re-renders,
                    // regardless of whether the caller wraps the callback or passes a raw setState directly.
                    notifyChange = function notifyChange(m) {
                        var _props_onFileMapChange;
                        return (_props_onFileMapChange = props.onFileMapChange) === null || _props_onFileMapChange === void 0 ? void 0 : _props_onFileMapChange.call(props, new Map(m));
                    };
                    hideLoading = function hideLoading() {};
                    fileList = Array.from(files);
                    fileList.forEach(prepareFile);
                    totalCount = fileList.length + existingFileCount;
                    isMaxExceeded = typeof props.maxFileCount === 'number' && totalCount > props.maxFileCount;
                    isMinNotMet = typeof props.minFileCount === 'number' && totalCount < props.minFileCount;
                    // Wrap all internal change notifications to use notifyChange so every update
                    // produces a new Map reference that React's state setter will always accept.
                    propsWithNotify = _object_spread_props(_object_spread({}, props), {
                        onFileMapChange: notifyChange
                    });
                    if (isMaxExceeded || isMinNotMet) {
                        hideLoading();
                        if (isMaxExceeded) {
                            ;
                            maxCount = props.maxFileCount;
                            rawMessage = getLocaleMessage(props.locale, 'markdownInput.maxFileCountExceeded', DEFAULT_MESSAGES.maxFileCountExceeded(maxCount));
                            errorMessage = rawMessage.replace(/\$\{maxFileCount\}/g, String(maxCount));
                            fileList.forEach(function(file) {
                                file.status = 'error';
                                file.errorCode = 'FILE_COUNT_EXCEEDED';
                                file.errorMessage = errorMessage;
                                if (file.uuid) map.set(file.uuid, file);
                            });
                            notifyChange(map);
                            (_props_onExceedMaxCount = props.onExceedMaxCount) === null || _props_onExceedMaxCount === void 0 ? void 0 : _props_onExceedMaxCount.call(props, {
                                maxCount: maxCount,
                                currentCount: existingFileCount,
                                selectedCount: fileList.length
                            });
                        }
                        return [
                            2
                        ];
                    }
                    // 验证通过后再添加到 fileMap
                    fileList.forEach(function(file) {
                        return updateFileMap(map, file, notifyChange);
                    });
                    _state.label = 1;
                case 1:
                    _state.trys.push([
                        1,
                        6,
                        7,
                        8
                    ]);
                    i = 0;
                    _state.label = 2;
                case 2:
                    if (!(i < fileList.length)) return [
                        3,
                        5
                    ];
                    return [
                        4,
                        processFile(fileList[i], i, map, propsWithNotify)
                    ];
                case 3:
                    _state.sent();
                    _state.label = 4;
                case 4:
                    i++;
                    return [
                        3,
                        2
                    ];
                case 5:
                    return [
                        3,
                        8
                    ];
                case 6:
                    error = _state.sent();
                    fileList.forEach(function(file) {
                        file.status = 'error';
                        updateFileMap(map, file, notifyChange);
                    });
                    return [
                        3,
                        8
                    ];
                case 7:
                    hideLoading();
                    return [
                        7
                    ];
                case 8:
                    return [
                        2
                    ];
            }
        });
    })();
};
var BUTTON_WITH_TITLE_STYLE = {
    display: 'flex',
    alignItems: 'center',
    gap: 4
};
var BUTTON_TITLE_STYLE = {
    font: 'var(--font-text-body-base)',
    letterSpacing: 'var(--letter-spacing-body-base, normal)',
    color: 'var(--color-gray-text-default)'
};
var ButtonContent = function ButtonContent(param) {
    var title = param.title;
    return /*#__PURE__*/ React.createElement(React.Fragment, null, /*#__PURE__*/ React.createElement(Paperclip, null), title !== null && title ? /*#__PURE__*/ React.createElement("div", {
        style: BUTTON_TITLE_STYLE
    }, title) : null);
};
/**
 * 附件上传按钮组件
 *
 * 提供文件附件上传功能，支持图片、文档、音频、视频等多种格式
 *
 * @example
 * ```tsx
 * <AttachmentButton
 *   supportedFormat={SupportedFileFormats.image}
 *   upload={uploadFile}
 *   fileMap={fileMap}
 *   onFileMapChange={setFileMap}
 *   uploadImage={handleUpload}
 * />
 * ```
 */ export var AttachmentButton = function AttachmentButton(param) {
    var disabled = param.disabled, uploadImage = param.uploadImage, title = param.title, supportedFormat = param.supportedFormat, locale = param.locale, render = param.render;
    var context = useContext(ConfigProvider.ConfigContext);
    var prefix = context === null || context === void 0 ? void 0 : context.getPrefixCls('agentic-md-editor-attachment-button');
    var _useStyle = useStyle(prefix), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
    var format = supportedFormat || SupportedFileFormats.image;
    var handleClick = function handleClick() {
        if (disabled) return;
        uploadImage === null || uploadImage === void 0 ? void 0 : uploadImage();
    };
    var buttonWithStyle = /*#__PURE__*/ React.createElement("div", {
        style: BUTTON_WITH_TITLE_STYLE
    }, /*#__PURE__*/ React.createElement(ButtonContent, {
        title: title
    }));
    var wrapper = render ? render({
        children: buttonWithStyle,
        supportedFormat: format,
        locale: locale
    }) : /*#__PURE__*/ React.createElement(AttachmentButtonPopover, {
        supportedFormat: format,
        uploadImage: uploadImage,
        locale: locale
    }, buttonWithStyle);
    return wrapSSR(/*#__PURE__*/ React.createElement("div", {
        className: classNames("".concat(prefix), hashId, _define_property({}, "".concat(prefix, "-disabled"), disabled)),
        onClick: handleClick,
        "data-testid": "attachment-button"
    }, wrapper));
};
