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 _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 { useContext, useEffect, useRef } from "react";
import { useRefFunction } from "../../Hooks/useRefFunction";
import { I18nContext } from "../../I18n";
import { SupportedFileFormats } from "../AttachmentButton/AttachmentButtonPopover";
import { isMobileDevice, isVivoOrOppoDevice, isWeChat } from "../AttachmentButton/utils";
import { upLoadFileToServer } from "../utils/uploadFile";
/**
 * 移动设备默认的文件类型 accept 值
 *
 * 覆盖 Office 三件套（excel/word/powerpoint）+ pdf + csv + txt + zip 等
 * 在移动端原生选择器里普遍能识别的 MIME 与扩展名集合。
 * 提取为模块级常量，避免每次 hook 调用时重新分配字符串。
 */ var MOBILE_DEFAULT_ACCEPT = 'application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,.csv,text/plain,application/x-zip-compressed';
/**
 * 文件上传管理器
 *
 * @description 封装文件上传相关的逻辑，包括上传、删除、重试等操作。
 * 历史位置 `src/MarkdownInputField/FileUploadManager/index.tsx` 现仅作为
 * re-export 兼容层；新代码请直接从本文件导入。
 */ export var useFileUploadManager = function useFileUploadManager(param) {
    var attachment = param.attachment, fileMap = param.fileMap, onFileMapChange = param.onFileMapChange;
    var locale = useContext(I18nContext).locale;
    /** 复用单个隐藏 file input，避免反复创建/卸载导致部分环境下选择器异常 */ var hiddenFileInputRef = useRef(null);
    useEffect(function() {
        return function() {
            var el = hiddenFileInputRef.current;
            if (el === null || el === void 0 ? void 0 : el.parentNode) {
                el.parentNode.removeChild(el);
            }
            hiddenFileInputRef.current = null;
        };
    }, []);
    var fileList = Array.from((fileMap === null || fileMap === void 0 ? void 0 : fileMap.values()) || []);
    var uploadingCount = fileList.filter(function(file) {
        return file.status === 'uploading';
    }).length;
    var errorCount = fileList.filter(function(file) {
        return file.status === 'error';
    }).length;
    var totalCount = fileList.length;
    var fileUploadSummary = {
        totalCount: totalCount,
        uploadingCount: uploadingCount,
        errorCount: errorCount,
        // 兜底把未知状态也按完成态处理，避免统计缺口
        doneCount: Math.max(0, totalCount - uploadingCount - errorCount)
    };
    var fileUploadStatus = fileUploadSummary.errorCount > 0 ? 'error' : fileUploadSummary.uploadingCount > 0 ? 'uploading' : 'done';
    // 向后兼容：无文件时视为已完成
    var fileUploadDone = fileUploadSummary.totalCount > 0 ? fileUploadStatus === 'done' : true;
    // 默认支持的文件格式
    var supportedFormat = (attachment === null || attachment === void 0 ? void 0 : attachment.supportedFormat) || SupportedFileFormats.image;
    /**
   * 更新附件文件列表
   */ var updateAttachmentFiles = useRefFunction(function(newFileMap) {
        onFileMapChange === null || onFileMapChange === void 0 ? void 0 : onFileMapChange(new Map(newFileMap));
    });
    /**
   * 根据支持的格式获取 accept 属性值
   * 优先级：微信 > 手机品牌（oppo/vivo）> 移动设备 > 相册模式 > 默认
   *
   * NOTE: 微信 / vivo|oppo / 移动端三个分支历史上分别由不同同事添加，
   * 当前都返回 `'*'`（让用户从系统文件浏览器自由选择）。这里保留三个分支
   * 以便日后差异化（例如微信里改成调起小程序选图）；如果未来彻底统一，
   * 可合并成 `if (isWeChat() || isVivoOrOppo() || isMobile()) return '*'`。
   */ var getAcceptValue = useRefFunction(function(forGallery) {
        // 相册模式
        if (forGallery) {
            return 'image/*';
        }
        var isMobile = isMobileDevice();
        var isVivoOrOppo = isVivoOrOppoDevice();
        var isWeChatEnv = isWeChat();
        var extensions = (supportedFormat === null || supportedFormat === void 0 ? void 0 : supportedFormat.extensions) || [];
        // 1. 微信环境最优先：设置为空字符串以打开文件浏览器
        if (isWeChatEnv) {
            return '*';
        }
        // 2. 手机品牌其次（oppo/vivo）：设置为空字符串以打开文件浏览器
        if (isVivoOrOppo) {
            return '*';
        }
        // 3. 移动设备其次：设置为空字符串以打开文件浏览器
        if (isMobile) {
            return '*';
        }
        // 4. 默认情况：使用具体扩展名列表
        return extensions.length > 0 ? extensions.map(function(ext) {
            return ".".concat(ext);
        }).join(',') : MOBILE_DEFAULT_ACCEPT;
    });
    /**
   * 上传图片
   */ var uploadImage = useRefFunction(function(forGallery) {
        return _async_to_generator(function() {
            var _ref, isUploading, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file, accept, input;
            return _ts_generator(this, function(_state) {
                // 检查是否有文件正在上传中
                isUploading = false;
                _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
                try {
                    for(_iterator = ((fileMap === null || fileMap === void 0 ? void 0 : fileMap.values()) || [])[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
                        file = _step.value;
                        if (file.status === 'uploading') {
                            isUploading = true;
                            break;
                        }
                    }
                } catch (err) {
                    _didIteratorError = true;
                    _iteratorError = err;
                } finally{
                    try {
                        if (!_iteratorNormalCompletion && _iterator.return != null) {
                            _iterator.return();
                        }
                    } finally{
                        if (_didIteratorError) {
                            throw _iteratorError;
                        }
                    }
                }
                if (isUploading) {
                    return [
                        2
                    ];
                }
                accept = getAcceptValue(forGallery || false);
                input = hiddenFileInputRef.current;
                if (!input) {
                    input = document.createElement('input');
                    input.type = 'file';
                    input.style.display = 'none';
                    hiddenFileInputRef.current = input;
                    document.body.appendChild(input);
                }
                input.accept = accept;
                input.multiple = (_ref = attachment === null || attachment === void 0 ? void 0 : attachment.allowMultiple) !== null && _ref !== void 0 ? _ref : true;
                input.value = '';
                input.onchange = function(e) {
                    return _async_to_generator(function() {
                        var selectedFiles, error;
                        return _ts_generator(this, function(_state) {
                            switch(_state.label){
                                case 0:
                                    if (input.dataset.readonly) {
                                        return [
                                            2
                                        ];
                                    }
                                    input.dataset.readonly = 'true';
                                    _state.label = 1;
                                case 1:
                                    _state.trys.push([
                                        1,
                                        3,
                                        4,
                                        5
                                    ]);
                                    selectedFiles = e.target.files;
                                    if (!selectedFiles || selectedFiles.length === 0) {
                                        return [
                                            2
                                        ];
                                    }
                                    // 检查选择的文件数量是否超过限制——超限时交由 upLoadFileToServer 统一处理
                                    // （upLoadFileToServer 内 validateFileCount 失败时会把文件以 error 状态入 map 并触发 onExceedMaxCount）
                                    return [
                                        4,
                                        upLoadFileToServer(selectedFiles, _object_spread_props(_object_spread({}, attachment), {
                                            fileMap: fileMap,
                                            onFileMapChange: function onFileMapChange(newFileMap) {
                                                updateAttachmentFiles(newFileMap);
                                            },
                                            locale: locale
                                        }))
                                    ];
                                case 2:
                                    _state.sent();
                                    return [
                                        3,
                                        5
                                    ];
                                case 3:
                                    error = _state.sent();
                                    console.error('Error uploading files:', error);
                                    return [
                                        3,
                                        5
                                    ];
                                case 4:
                                    input.value = '';
                                    delete input.dataset.readonly;
                                    return [
                                        7
                                    ];
                                case 5:
                                    return [
                                        2
                                    ];
                            }
                        });
                    })();
                };
                if (input.dataset.readonly) {
                    return [
                        2
                    ];
                }
                input.click();
                return [
                    2
                ];
            });
        })();
    });
    /**
   * 处理文件删除
   */ var handleFileRemoval = useRefFunction(function(file) {
        return _async_to_generator(function() {
            var _attachment_onDelete, map, error;
            return _ts_generator(this, function(_state) {
                switch(_state.label){
                    case 0:
                        _state.trys.push([
                            0,
                            2,
                            ,
                            3
                        ]);
                        return [
                            4,
                            attachment === null || attachment === void 0 ? void 0 : (_attachment_onDelete = attachment.onDelete) === null || _attachment_onDelete === void 0 ? void 0 : _attachment_onDelete.call(attachment, file)
                        ];
                    case 1:
                        _state.sent();
                        map = new Map(fileMap);
                        map.delete(file.uuid);
                        updateAttachmentFiles(map);
                        return [
                            3,
                            3
                        ];
                    case 2:
                        error = _state.sent();
                        console.error('Error removing file:', error);
                        return [
                            3,
                            3
                        ];
                    case 3:
                        return [
                            2
                        ];
                }
            });
        })();
    });
    /**
   * 处理文件重试
   */ var handleFileRetry = useRefFunction(function(file) {
        return _async_to_generator(function() {
            var map, url, isSuccess, uploadResult, _attachment_onUploadError, error, _attachment_onUploadError1;
            return _ts_generator(this, function(_state) {
                switch(_state.label){
                    case 0:
                        map = new Map(fileMap);
                        _state.label = 1;
                    case 1:
                        _state.trys.push([
                            1,
                            6,
                            ,
                            7
                        ]);
                        file.status = 'uploading';
                        map.set(file.uuid || '', file);
                        updateAttachmentFiles(map);
                        isSuccess = false;
                        if (!(attachment === null || attachment === void 0 ? void 0 : attachment.uploadWithResponse)) return [
                            3,
                            3
                        ];
                        return [
                            4,
                            attachment.uploadWithResponse(file, 0)
                        ];
                    case 2:
                        uploadResult = _state.sent();
                        url = uploadResult.fileUrl;
                        isSuccess = uploadResult.uploadStatus === 'SUCCESS';
                        // 将完整的响应数据存储到 file 对象中
                        file.uploadResponse = uploadResult;
                        return [
                            3,
                            5
                        ];
                    case 3:
                        if (!(attachment === null || attachment === void 0 ? void 0 : attachment.upload)) return [
                            3,
                            5
                        ];
                        return [
                            4,
                            attachment.upload(file, 0)
                        ];
                    case 4:
                        url = _state.sent();
                        isSuccess = !!url;
                        _state.label = 5;
                    case 5:
                        if (isSuccess && url) {
                            file.status = 'done';
                            file.url = url;
                            map.set(file.uuid || '', file);
                            updateAttachmentFiles(map);
                        } else {
                            ;
                            file.status = 'error';
                            map.set(file.uuid || '', file);
                            updateAttachmentFiles(map);
                            attachment === null || attachment === void 0 ? void 0 : (_attachment_onUploadError = attachment.onUploadError) === null || _attachment_onUploadError === void 0 ? void 0 : _attachment_onUploadError.call(attachment, {
                                file: file,
                                error: null
                            });
                        }
                        return [
                            3,
                            7
                        ];
                    case 6:
                        error = _state.sent();
                        if (attachment === null || attachment === void 0 ? void 0 : attachment.removeFileOnUploadError) {
                            map.delete(file.uuid || '');
                            updateAttachmentFiles(map);
                        } else {
                            file.status = 'error';
                            map.set(file.uuid || '', file);
                            updateAttachmentFiles(map);
                        }
                        attachment === null || attachment === void 0 ? void 0 : (_attachment_onUploadError1 = attachment.onUploadError) === null || _attachment_onUploadError1 === void 0 ? void 0 : _attachment_onUploadError1.call(attachment, {
                            file: file,
                            error: error
                        });
                        console.error('Error retrying file upload:', error);
                        return [
                            3,
                            7
                        ];
                    case 7:
                        return [
                            2
                        ];
                }
            });
        })();
    });
    return {
        fileMap: fileMap,
        fileUploadDone: fileUploadDone,
        fileUploadStatus: fileUploadStatus,
        fileUploadSummary: fileUploadSummary,
        supportedFormat: supportedFormat,
        uploadImage: uploadImage,
        updateAttachmentFiles: updateAttachmentFiles,
        handleFileRemoval: handleFileRemoval,
        handleFileRetry: handleFileRetry
    };
};
