export { CDNProviderError, FileProcessingError, FileServiceError, FileUploadError, StorageProviderError } from '../chunk-CIVO4R6N.mjs';
import '../chunk-WMJKH4XE.mjs';
import React2, { useState, useRef, useCallback, useEffect } from 'react';
import { clsx } from 'clsx';
import { Upload, AlertCircle, CheckCircle2, Loader2, X, Image, Film, Music, FileText } from 'lucide-react';

// src/universalFile/constants.ts
var UNIVERSAL_FILE_VERSION = "1.0.0";
var UNIVERSAL_FILE_NAME = "@qhr123/sa2kit/universalFile";
var DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024;
var DEFAULT_MAX_IMAGE_SIZE = 10 * 1024 * 1024;
var DEFAULT_MAX_VIDEO_SIZE = 500 * 1024 * 1024;
var DEFAULT_MAX_AUDIO_SIZE = 50 * 1024 * 1024;
var DEFAULT_MAX_DOCUMENT_SIZE = 20 * 1024 * 1024;
var IMAGE_MIME_TYPES = [
  "image/jpeg",
  "image/jpg",
  "image/png",
  "image/gif",
  "image/webp",
  "image/svg+xml"
];
var VIDEO_MIME_TYPES = [
  "video/mp4",
  "video/mpeg",
  "video/quicktime",
  "video/x-msvideo",
  "video/webm"
];
var AUDIO_MIME_TYPES = ["audio/mpeg", "audio/mp3", "audio/wav", "audio/ogg", "audio/aac"];
var DOCUMENT_MIME_TYPES = [
  "application/pdf",
  "application/msword",
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  "application/vnd.ms-excel",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  "application/vnd.ms-powerpoint",
  "application/vnd.openxmlformats-officedocument.presentationml.presentation",
  "text/plain"
];
var ALL_SUPPORTED_MIME_TYPES = [
  ...IMAGE_MIME_TYPES,
  ...VIDEO_MIME_TYPES,
  ...AUDIO_MIME_TYPES,
  ...DOCUMENT_MIME_TYPES
];
var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"];
var VIDEO_EXTENSIONS = [".mp4", ".mpeg", ".mov", ".avi", ".webm"];
var AUDIO_EXTENSIONS = [".mp3", ".wav", ".ogg", ".aac"];
var DOCUMENT_EXTENSIONS = [
  ".pdf",
  ".doc",
  ".docx",
  ".xls",
  ".xlsx",
  ".ppt",
  ".pptx",
  ".txt"
];
var API_BASE_PATH = "/api/universal-file";
var API_ENDPOINTS = {
  /** 上传文件 */
  UPLOAD: API_BASE_PATH + "/upload",
  /** 获取文件URL */
  GET_URL: (fileId) => API_BASE_PATH + "/files/" + fileId + "/url",
  /** 获取文件元数据 */
  GET_METADATA: (fileId) => API_BASE_PATH + "/files/" + fileId,
  /** 删除文件 */
  DELETE: (fileId) => API_BASE_PATH + "/files/" + fileId,
  /** 查询文件列表 */
  QUERY: API_BASE_PATH + "/files",
  /** 批量删除 */
  BATCH_DELETE: API_BASE_PATH + "/files/batch-delete",
  /** 获取上传进度 */
  GET_PROGRESS: (fileId) => API_BASE_PATH + "/upload/" + fileId + "/progress"
};
var ERROR_CODES = {
  /** 文件上传错误 */
  FILE_UPLOAD_ERROR: "FILE_UPLOAD_ERROR",
  /** 文件大小超限 */
  FILE_SIZE_EXCEEDED: "FILE_SIZE_EXCEEDED",
  /** 文件类型不支持 */
  FILE_TYPE_NOT_SUPPORTED: "FILE_TYPE_NOT_SUPPORTED",
  /** 文件不存在 */
  FILE_NOT_FOUND: "FILE_NOT_FOUND",
  /** 文件处理错误 */
  FILE_PROCESSING_ERROR: "FILE_PROCESSING_ERROR",
  /** 存储提供者错误 */
  STORAGE_PROVIDER_ERROR: "STORAGE_PROVIDER_ERROR",
  /** CDN提供者错误 */
  CDN_PROVIDER_ERROR: "CDN_PROVIDER_ERROR",
  /** 网络错误 */
  NETWORK_ERROR: "NETWORK_ERROR",
  /** 超时错误 */
  TIMEOUT_ERROR: "TIMEOUT_ERROR",
  /** 未授权 */
  UNAUTHORIZED: "UNAUTHORIZED",
  /** 权限不足 */
  FORBIDDEN: "FORBIDDEN",
  /** 服务器错误 */
  SERVER_ERROR: "SERVER_ERROR"
};
var DEFAULT_PAGE_SIZE = 20;
var DEFAULT_REQUEST_TIMEOUT = 3e4;
var DEFAULT_UPLOAD_TIMEOUT = 3e5;
var DEFAULT_CHUNK_SIZE = 5 * 1024 * 1024;

// src/universalFile/utils.ts
function formatFileSize(bytes) {
  if (bytes === 0) return "0 B";
  const units = ["B", "KB", "MB", "GB", "TB"];
  const k = 1024;
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return (bytes / Math.pow(k, i)).toFixed(2) + " " + units[i];
}
function parseFileSize(sizeStr) {
  const match = sizeStr.match(/^(\d+(?:\.\d+)?)\s*([KMGT]?B)$/i);
  if (!match || !match[1] || !match[2]) return 0;
  const value = parseFloat(match[1]);
  const unit = match[2].toUpperCase();
  const units = {
    B: 1,
    KB: 1024,
    MB: 1024 * 1024,
    GB: 1024 * 1024 * 1024,
    TB: 1024 * 1024 * 1024 * 1024
  };
  return value * (units[unit] || 1);
}
function getFileExtension(fileName) {
  const lastDot = fileName.lastIndexOf(".");
  if (lastDot === -1) return "";
  return fileName.substring(lastDot).toLowerCase();
}
function getMimeTypeFromFileName(fileName) {
  const ext = getFileExtension(fileName);
  const mimeMap = {
    ".jpg": "image/jpeg",
    ".jpeg": "image/jpeg",
    ".png": "image/png",
    ".gif": "image/gif",
    ".webp": "image/webp",
    ".svg": "image/svg+xml",
    ".pdf": "application/pdf",
    ".txt": "text/plain",
    ".mp4": "video/mp4",
    ".avi": "video/x-msvideo",
    ".mov": "video/quicktime",
    ".mp3": "audio/mpeg",
    ".wav": "audio/wav",
    ".ogg": "audio/ogg",
    ".doc": "application/msword",
    ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    ".xls": "application/vnd.ms-excel",
    ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  };
  return mimeMap[ext] || "application/octet-stream";
}
function isMimeTypeSupported(mimeType, allowedTypes) {
  if (allowedTypes && allowedTypes.length > 0) {
    return allowedTypes.includes(mimeType);
  }
  return IMAGE_MIME_TYPES.includes(mimeType) || VIDEO_MIME_TYPES.includes(mimeType) || AUDIO_MIME_TYPES.includes(mimeType) || DOCUMENT_MIME_TYPES.includes(mimeType);
}
function isImageFile(mimeType) {
  return IMAGE_MIME_TYPES.includes(mimeType);
}
function isVideoFile(mimeType) {
  return VIDEO_MIME_TYPES.includes(mimeType);
}
function isAudioFile(mimeType) {
  return AUDIO_MIME_TYPES.includes(mimeType);
}
function isDocumentFile(mimeType) {
  return DOCUMENT_MIME_TYPES.includes(mimeType);
}
function getFileCategory(mimeType) {
  if (isImageFile(mimeType)) return "image";
  if (isVideoFile(mimeType)) return "video";
  if (isAudioFile(mimeType)) return "audio";
  if (isDocumentFile(mimeType)) return "document";
  return "other";
}
function validateFileName(fileName) {
  const invalidChars = /[<>:"|?*\/\\]/;
  if (invalidChars.test(fileName)) {
    return false;
  }
  if (fileName.length === 0 || fileName.length > 255) {
    return false;
  }
  if (fileName.startsWith(".")) {
    return false;
  }
  return true;
}
function sanitizeFileName(fileName) {
  return fileName.replace(/[<>:"|?*\/\\]/g, "_").replace(/^\.+/, "").substring(0, 255);
}
function generateUniqueFileName(originalName, fileId) {
  const ext = getFileExtension(originalName);
  return fileId + ext;
}
function generateStoragePath(moduleId, fileName, options) {
  const parts = [];
  if (options?.customPrefix) {
    parts.push(options.customPrefix);
  }
  parts.push(moduleId);
  if (options?.businessId) {
    parts.push(options.businessId);
  }
  if (options?.useDate !== false) {
    const date = /* @__PURE__ */ new Date();
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    parts.push(String(year), month, day);
  }
  parts.push(fileName);
  return parts.join("/");
}
function parseStoragePath(path) {
  const parts = path.split("/");
  const fileName = parts[parts.length - 1] || "";
  return {
    moduleId: parts[0] || void 0,
    businessId: parts.length > 5 ? parts[1] : void 0,
    year: parts.length > 3 ? parts[parts.length - 4] : void 0,
    month: parts.length > 2 ? parts[parts.length - 3] : void 0,
    day: parts.length > 1 ? parts[parts.length - 2] : void 0,
    fileName
  };
}
function validateFileSize(file, maxSize) {
  if (file.size > maxSize) {
    return {
      valid: false,
      error: "\u6587\u4EF6\u5927\u5C0F\u8D85\u8FC7\u9650\u5236: " + formatFileSize(file.size) + " > " + formatFileSize(maxSize)
    };
  }
  return { valid: true };
}
function validateFileType(file, allowedTypes) {
  const mimeType = file.type || getMimeTypeFromFileName(file.name);
  if (!isMimeTypeSupported(mimeType, allowedTypes)) {
    return {
      valid: false,
      error: "\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: " + mimeType
    };
  }
  return { valid: true };
}
function validateFile(file, options) {
  const errors = [];
  if (!validateFileName(file.name)) {
    errors.push("\u6587\u4EF6\u540D\u5305\u542B\u975E\u6CD5\u5B57\u7B26\u6216\u957F\u5EA6\u4E0D\u5408\u6CD5");
  }
  if (options?.maxSize) {
    const sizeResult = validateFileSize(file, options.maxSize);
    if (!sizeResult.valid && sizeResult.error) {
      errors.push(sizeResult.error);
    }
  }
  if (options?.allowedTypes) {
    const typeResult = validateFileType(file, options.allowedTypes);
    if (!typeResult.valid && typeResult.error) {
      errors.push(typeResult.error);
    }
  }
  return {
    valid: errors.length === 0,
    errors
  };
}
function buildQueryString(params) {
  const searchParams = new URLSearchParams();
  Object.entries(params).forEach(([key, value]) => {
    if (value !== void 0 && value !== null) {
      if (Array.isArray(value)) {
        value.forEach((v) => searchParams.append(key, String(v)));
      } else {
        searchParams.append(key, String(value));
      }
    }
  });
  const queryString = searchParams.toString();
  return queryString ? "?" + queryString : "";
}
function parseQueryString(url) {
  const params = {};
  const urlObj = new URL(url, window.location.origin);
  urlObj.searchParams.forEach((value, key) => {
    params[key] = value;
  });
  return params;
}
function calculateProgress(uploadedBytes, totalBytes) {
  if (totalBytes === 0) return 0;
  return Math.min(Math.round(uploadedBytes / totalBytes * 100), 100);
}
function calculateSpeed(uploadedBytes, elapsedTime) {
  if (elapsedTime === 0) return 0;
  return uploadedBytes / (elapsedTime / 1e3);
}
function calculateRemainingTime(uploadedBytes, totalBytes, speed) {
  if (speed === 0) return 0;
  const remainingBytes = totalBytes - uploadedBytes;
  return Math.round(remainingBytes / speed);
}
function createFileError(code, message, details) {
  return {
    code,
    message,
    details,
    timestamp: /* @__PURE__ */ new Date()
  };
}
function formatErrorMessage(error) {
  if (error instanceof Error) {
    return error.message;
  }
  if (typeof error === "string") {
    return error;
  }
  if (error && typeof error === "object" && "message" in error) {
    return String(error.message);
  }
  return "\u672A\u77E5\u9519\u8BEF";
}
function readFileAsBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      const result = reader.result;
      const base64 = result.split(",")[1] || "";
      resolve(base64);
    };
    reader.onerror = () => {
      reject(new Error("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25"));
    };
    reader.readAsDataURL(file);
  });
}
function readFileAsArrayBuffer(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      resolve(reader.result);
    };
    reader.onerror = () => {
      reject(new Error("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25"));
    };
    reader.readAsArrayBuffer(file);
  });
}
function readFileAsText(file, encoding = "UTF-8") {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => {
      resolve(reader.result);
    };
    reader.onerror = () => {
      reject(new Error("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25"));
    };
    reader.readAsText(file, encoding);
  });
}

// src/universalFile/client.ts
var UniversalFileClient = class {
  constructor(config = {}) {
    this.config = {
      baseUrl: config.baseUrl || "",
      timeout: config.timeout || DEFAULT_REQUEST_TIMEOUT,
      uploadTimeout: config.uploadTimeout || DEFAULT_UPLOAD_TIMEOUT,
      headers: config.headers || {}
    };
  }
  // ============= 文件上传API =============
  /**
   * 上传文件
   */
  async uploadFile(fileInfo, onProgress) {
    const url = this.config.baseUrl + API_ENDPOINTS.UPLOAD;
    const startTime = Date.now();
    const formData = new FormData();
    formData.append("file", fileInfo.file);
    formData.append("moduleId", fileInfo.moduleId);
    if (fileInfo.businessId) {
      formData.append("businessId", fileInfo.businessId);
    }
    if (fileInfo.permission) {
      formData.append("permission", fileInfo.permission);
    }
    if (fileInfo.customPath) {
      formData.append("customPath", fileInfo.customPath);
    }
    if (fileInfo.metadata) {
      formData.append("metadata", JSON.stringify(fileInfo.metadata));
    }
    if (fileInfo.needsProcessing !== void 0) {
      formData.append("needsProcessing", String(fileInfo.needsProcessing));
    }
    if (fileInfo.processingOptions) {
      formData.append("processingOptions", JSON.stringify(fileInfo.processingOptions));
    }
    try {
      console.log("\u{1F4E4} [UniversalFileClient] \u5F00\u59CB\u4E0A\u4F20\u6587\u4EF6:", {
        url,
        fileName: fileInfo.file.name,
        fileSize: fileInfo.file.size,
        moduleId: fileInfo.moduleId,
        businessId: fileInfo.businessId
      });
      return await new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.withCredentials = true;
        xhr.upload.addEventListener("progress", (event) => {
          if (event.lengthComputable && onProgress) {
            const elapsedTime = Date.now() - startTime;
            const speed = event.loaded / (elapsedTime / 1e3);
            const remainingBytes = event.total - event.loaded;
            const remainingTime = speed > 0 ? remainingBytes / speed : 0;
            const progress = {
              fileId: "",
              // 暂时为空，上传完成后会有
              status: "uploading",
              progress: Math.round(event.loaded / event.total * 100),
              uploadedBytes: event.loaded,
              totalBytes: event.total,
              speed,
              remainingTime
            };
            onProgress(progress);
          }
        });
        xhr.addEventListener("load", () => {
          console.log("\u{1F4E5} [UniversalFileClient] \u4E0A\u4F20\u54CD\u5E94:", {
            status: xhr.status,
            statusText: xhr.statusText,
            responseLength: xhr.responseText?.length
          });
          if (xhr.status >= 200 && xhr.status < 300) {
            try {
              const response = JSON.parse(xhr.responseText);
              console.log("\u2705 [UniversalFileClient] \u89E3\u6790\u54CD\u5E94\u6210\u529F:", response);
              const fileData = response.file || response.data || response;
              const fileMetadata = this.transformFileMetadataFromAPI(fileData);
              if (onProgress) {
                onProgress({
                  fileId: fileMetadata.id,
                  status: "completed",
                  progress: 100,
                  uploadedBytes: fileInfo.file.size,
                  totalBytes: fileInfo.file.size,
                  speed: 0,
                  remainingTime: 0
                });
              }
              resolve(fileMetadata);
            } catch (error) {
              console.error("\u274C [UniversalFileClient] \u89E3\u6790\u54CD\u5E94\u5931\u8D25:", error, xhr.responseText);
              reject(new Error("\u89E3\u6790\u54CD\u5E94\u5931\u8D25"));
            }
          } else {
            console.error("\u274C [UniversalFileClient] \u4E0A\u4F20\u5931\u8D25:", xhr.status, xhr.statusText, xhr.responseText);
            reject(new Error("\u4E0A\u4F20\u5931\u8D25: " + xhr.statusText));
          }
        });
        xhr.addEventListener("error", (event) => {
          console.error("\u274C [UniversalFileClient] \u7F51\u7EDC\u9519\u8BEF:", event);
          if (onProgress) {
            onProgress({
              fileId: "",
              status: "failed",
              progress: 0,
              uploadedBytes: 0,
              totalBytes: fileInfo.file.size,
              speed: 0,
              remainingTime: 0,
              error: "\u7F51\u7EDC\u9519\u8BEF"
            });
          }
          reject(new Error("\u4E0A\u4F20\u5931\u8D25: \u7F51\u7EDC\u9519\u8BEF"));
        });
        xhr.addEventListener("timeout", () => {
          if (onProgress) {
            onProgress({
              fileId: "",
              status: "failed",
              progress: 0,
              uploadedBytes: 0,
              totalBytes: fileInfo.file.size,
              speed: 0,
              remainingTime: 0,
              error: "\u4E0A\u4F20\u8D85\u65F6"
            });
          }
          reject(new Error("\u4E0A\u4F20\u8D85\u65F6"));
        });
        xhr.open("POST", url);
        xhr.timeout = this.config.uploadTimeout;
        Object.entries(this.config.headers).forEach(([key, value]) => {
          xhr.setRequestHeader(key, value);
        });
        xhr.send(formData);
      });
    } catch (error) {
      throw createFileError(
        ERROR_CODES.FILE_UPLOAD_ERROR,
        "\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: " + formatErrorMessage(error),
        { fileInfo, originalError: error }
      );
    }
  }
  // ============= 文件查询API =============
  /**
   * 获取文件访问URL
   */
  async getFileUrl(fileId, expiresIn) {
    const url = this.config.baseUrl + API_ENDPOINTS.GET_URL(fileId) + (expiresIn ? `?expiresIn=${expiresIn}` : "");
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "GET",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        throw new Error("\u83B7\u53D6\u6587\u4EF6URL\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return data.url;
    } catch (error) {
      throw createFileError(
        ERROR_CODES.NETWORK_ERROR,
        "\u83B7\u53D6\u6587\u4EF6URL\u5931\u8D25: " + formatErrorMessage(error),
        { fileId, expiresIn, originalError: error }
      );
    }
  }
  /**
   * 获取文件元数据
   */
  async getFileMetadata(fileId) {
    const url = this.config.baseUrl + API_ENDPOINTS.GET_METADATA(fileId);
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "GET",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        if (response.status === 404) {
          throw createFileError(ERROR_CODES.FILE_NOT_FOUND, "\u6587\u4EF6\u4E0D\u5B58\u5728", { fileId });
        }
        throw new Error("\u83B7\u53D6\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return this.transformFileMetadataFromAPI(data.file);
    } catch (error) {
      throw createFileError(
        ERROR_CODES.NETWORK_ERROR,
        "\u83B7\u53D6\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25: " + formatErrorMessage(error),
        { fileId, originalError: error }
      );
    }
  }
  /**
   * 查询文件列表
   */
  async queryFiles(options) {
    const queryString = buildQueryString({
      moduleId: options.moduleId,
      businessId: options.businessId,
      uploaderId: options.uploaderId,
      mimeType: options.mimeType,
      minSize: options.minSize,
      maxSize: options.maxSize,
      startTime: options.startTime?.toISOString(),
      endTime: options.endTime?.toISOString(),
      keyword: options.keyword,
      tags: options.tags,
      sortBy: options.sortBy,
      sortOrder: options.sortOrder,
      page: options.page,
      pageSize: options.pageSize
    });
    const url = this.config.baseUrl + API_ENDPOINTS.QUERY + queryString;
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "GET",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        console.error("\u274C [UniversalFileClient] \u67E5\u8BE2\u6587\u4EF6\u5217\u8868\u5931\u8D25:", response.status, response.statusText);
        throw new Error("\u67E5\u8BE2\u6587\u4EF6\u5217\u8868\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      console.log("\u{1F4E5} [UniversalFileClient] \u67E5\u8BE2\u6587\u4EF6\u5217\u8868\u54CD\u5E94:", {
        itemsCount: data.items?.length,
        total: data.total,
        page: data.page
      });
      if (!data.items || !Array.isArray(data.items)) {
        console.error("\u274C [UniversalFileClient] \u54CD\u5E94\u683C\u5F0F\u9519\u8BEF: items \u4E0D\u662F\u6570\u7EC4", data);
        return {
          items: [],
          total: 0,
          page: 1,
          pageSize: 20,
          totalPages: 0,
          hasNext: false,
          hasPrev: false
        };
      }
      return {
        items: data.items.map((item) => this.transformFileMetadataFromAPI(item)),
        total: data.total,
        page: data.page,
        pageSize: data.pageSize,
        totalPages: data.totalPages,
        hasNext: data.hasNext,
        hasPrev: data.hasPrev
      };
    } catch (error) {
      throw createFileError(
        ERROR_CODES.NETWORK_ERROR,
        "\u67E5\u8BE2\u6587\u4EF6\u5217\u8868\u5931\u8D25: " + formatErrorMessage(error),
        { options, originalError: error }
      );
    }
  }
  // ============= 文件删除API =============
  /**
   * 删除文件
   */
  async deleteFile(fileId) {
    const url = this.config.baseUrl + API_ENDPOINTS.DELETE(fileId);
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "DELETE",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        if (response.status === 404) {
          throw createFileError(ERROR_CODES.FILE_NOT_FOUND, "\u6587\u4EF6\u4E0D\u5B58\u5728", { fileId });
        }
        throw new Error("\u5220\u9664\u6587\u4EF6\u5931\u8D25: " + response.statusText);
      }
    } catch (error) {
      throw createFileError(
        ERROR_CODES.NETWORK_ERROR,
        "\u5220\u9664\u6587\u4EF6\u5931\u8D25: " + formatErrorMessage(error),
        { fileId, originalError: error }
      );
    }
  }
  /**
   * 批量删除文件
   */
  async batchDeleteFiles(fileIds) {
    const url = this.config.baseUrl + API_ENDPOINTS.BATCH_DELETE;
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "POST",
        headers: {
          ...this.getHeaders(),
          "Content-Type": "application/json"
        },
        body: JSON.stringify({ fileIds })
      });
      if (!response.ok) {
        throw new Error("\u6279\u91CF\u5220\u9664\u6587\u4EF6\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return data.result;
    } catch (error) {
      throw createFileError(
        ERROR_CODES.NETWORK_ERROR,
        "\u6279\u91CF\u5220\u9664\u6587\u4EF6\u5931\u8D25: " + formatErrorMessage(error),
        { fileIds, originalError: error }
      );
    }
  }
  // ============= 上传进度API =============
  /**
   * 获取上传进度
   */
  async getUploadProgress(fileId) {
    const url = this.config.baseUrl + API_ENDPOINTS.GET_PROGRESS(fileId);
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "GET",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        throw new Error("\u83B7\u53D6\u4E0A\u4F20\u8FDB\u5EA6\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return data.progress;
    } catch (error) {
      throw createFileError(
        ERROR_CODES.NETWORK_ERROR,
        "\u83B7\u53D6\u4E0A\u4F20\u8FDB\u5EA6\u5931\u8D25: " + formatErrorMessage(error),
        { fileId, originalError: error }
      );
    }
  }
  // ============= 私有辅助方法 =============
  /**
   * 获取请求头
   */
  getHeaders() {
    return {
      ...this.config.headers
    };
  }
  /**
   * 带超时的fetch请求
   */
  async fetchWithTimeout(url, options) {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
    try {
      const response = await fetch(url, {
        ...options,
        signal: controller.signal,
        credentials: "include"
        // 携带 cookie 用于授权
      });
      return response;
    } catch (error) {
      if (error instanceof Error && error.name === "AbortError") {
        throw createFileError(ERROR_CODES.TIMEOUT_ERROR, "\u8BF7\u6C42\u8D85\u65F6", {
          url,
          timeout: this.config.timeout
        });
      }
      throw error;
    } finally {
      clearTimeout(timeoutId);
    }
  }
  /**
   * 转换API返回的文件元数据
   */
  transformFileMetadataFromAPI(apiData) {
    return {
      id: apiData.id,
      originalName: apiData.originalName,
      storageName: apiData.storageName || apiData.storedName,
      size: apiData.size,
      mimeType: apiData.mimeType,
      extension: apiData.extension,
      hash: apiData.hash || apiData.md5Hash || apiData.sha256Hash,
      uploadTime: new Date(apiData.uploadTime),
      permission: apiData.permission || "public",
      uploaderId: apiData.uploaderId,
      moduleId: apiData.moduleId,
      businessId: apiData.businessId,
      storageProvider: apiData.storageProvider || "local",
      storagePath: apiData.storagePath,
      cdnUrl: apiData.cdnUrl,
      accessCount: apiData.accessCount,
      lastAccessTime: apiData.lastAccessTime ? new Date(apiData.lastAccessTime) : void 0,
      expiresAt: apiData.expiresAt ? new Date(apiData.expiresAt) : void 0,
      metadata: apiData.metadata
    };
  }
};
var universalFileClient = new UniversalFileClient();
function createFileClient(config) {
  return new UniversalFileClient(config);
}
var FileUploader = ({
  fileService,
  moduleId,
  businessId,
  acceptedTypes = [],
  maxFileSize = 100,
  // 100MB
  maxFiles = 10,
  multiple = true,
  enableProcessing = false,
  defaultProcessingOptions,
  onUploadSuccess,
  onUploadError,
  onProgress,
  className = "",
  disabled = false,
  mode = "normal"
}) => {
  const [uploadingFiles, setUploadingFiles] = useState([]);
  const [isDragOver, setIsDragOver] = useState(false);
  const [completedFiles, setCompletedFiles] = useState([]);
  const fileInputRef = useRef(null);
  const getFileIcon = (mimeType) => {
    if (mimeType.startsWith("image/")) return /* @__PURE__ */ React2.createElement(Image, { className: "w-5 h-5" });
    if (mimeType.startsWith("video/")) return /* @__PURE__ */ React2.createElement(Film, { className: "w-5 h-5" });
    if (mimeType.startsWith("audio/")) return /* @__PURE__ */ React2.createElement(Music, { className: "w-5 h-5" });
    return /* @__PURE__ */ React2.createElement(FileText, { className: "w-5 h-5" });
  };
  const validateFile2 = (file) => {
    if (file.size > maxFileSize * 1024 * 1024) {
      return "\u6587\u4EF6\u5927\u5C0F\u4E0D\u80FD\u8D85\u8FC7 " + maxFileSize + "MB";
    }
    if (acceptedTypes.length > 0 && !acceptedTypes.includes(file.type)) {
      return "\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: " + file.type;
    }
    return null;
  };
  const uploadFile = useCallback(
    async (file) => {
      const fileId = "upload_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9);
      const error = validateFile2(file);
      if (error) {
        onUploadError?.(error);
        return;
      }
      const initialProgress = {
        fileId,
        status: "pending",
        progress: 0,
        uploadedBytes: 0,
        totalBytes: file.size,
        speed: 0,
        remainingTime: 0
      };
      const uploadingFile = {
        id: fileId,
        file,
        progress: initialProgress
      };
      setUploadingFiles((prev) => [...prev, uploadingFile]);
      try {
        const uploadInfo = {
          file,
          moduleId,
          businessId,
          permission: "public",
          needsProcessing: enableProcessing,
          processingOptions: defaultProcessingOptions
        };
        const result = await fileService.uploadFile(
          uploadInfo,
          void 0,
          // 使用默认存储类型
          (progress) => {
            setUploadingFiles(
              (prev) => prev.map((f) => f.id === fileId ? { ...f, progress } : f)
            );
            const allProgress = uploadingFiles.map((f) => f.progress);
            onProgress?.(allProgress);
          }
        );
        setUploadingFiles((prev) => prev.filter((f) => f.id !== fileId));
        setCompletedFiles((prev) => [...prev, result]);
        onUploadSuccess?.([result]);
      } catch (error2) {
        console.error("\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25:", error2);
        const errorMessage = error2 instanceof Error ? error2.message : "\u4E0A\u4F20\u5931\u8D25";
        setUploadingFiles(
          (prev) => prev.map((f) => f.id === fileId ? { ...f, error: errorMessage } : f)
        );
        onUploadError?.(errorMessage);
      }
    },
    [
      fileService,
      moduleId,
      businessId,
      enableProcessing,
      defaultProcessingOptions,
      maxFileSize,
      acceptedTypes,
      onUploadSuccess,
      onUploadError,
      onProgress,
      uploadingFiles
    ]
  );
  const handleFileSelect = useCallback(
    (files) => {
      const fileArray = Array.from(files);
      if (completedFiles.length + uploadingFiles.length + fileArray.length > maxFiles) {
        onUploadError?.("\u6700\u591A\u53EA\u80FD\u4E0A\u4F20 " + maxFiles + " \u4E2A\u6587\u4EF6");
        return;
      }
      fileArray.forEach(uploadFile);
    },
    [completedFiles.length, uploadingFiles.length, maxFiles, onUploadError, uploadFile]
  );
  const handleInputChange = (event) => {
    const files = event.target.files;
    if (files && files.length > 0) {
      handleFileSelect(files);
    }
    event.target.value = "";
  };
  const handleDragOver = (event) => {
    event.preventDefault();
    setIsDragOver(true);
  };
  const handleDragLeave = (event) => {
    event.preventDefault();
    setIsDragOver(false);
  };
  const handleDrop = (event) => {
    event.preventDefault();
    setIsDragOver(false);
    const files = event.dataTransfer.files;
    if (files.length > 0) {
      handleFileSelect(files);
    }
  };
  const handleClick = () => {
    if (!disabled) {
      fileInputRef.current?.click();
    }
  };
  const removeUploadingFile = (fileId) => {
    setUploadingFiles((prev) => prev.filter((f) => f.id !== fileId));
  };
  const removeCompletedFile = (fileId) => {
    setCompletedFiles((prev) => prev.filter((f) => f.id !== fileId));
  };
  const formatFileSize2 = (bytes) => {
    if (bytes === 0) return "0 B";
    const k = 1024;
    const sizes = ["B", "KB", "MB", "GB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  };
  const formatProgress = (progress) => {
    switch (progress.status) {
      case "pending":
        return "\u51C6\u5907\u4E2D...";
      case "uploading":
        return "\u4E0A\u4F20\u4E2D " + progress.progress.toFixed(1) + "%";
      case "processing":
        return "\u5904\u7406\u4E2D...";
      case "completed":
        return "\u5B8C\u6210";
      case "failed":
        return "\u5931\u8D25";
      default:
        return "\u672A\u77E5\u72B6\u6001";
    }
  };
  const containerClasses = clsx(
    "border-2 border-dashed rounded-lg transition-all duration-200",
    isDragOver ? "border-blue-400 bg-blue-50 dark:bg-blue-900/20" : "border-gray-300 dark:border-gray-600",
    disabled ? "opacity-50 cursor-not-allowed" : "hover:border-blue-400 cursor-pointer",
    className
  );
  const uploadAreaClasses = clsx(
    "p-6 text-center",
    mode === "compact" ? "p-4" : mode === "detailed" ? "p-8" : "p-6"
  );
  return /* @__PURE__ */ React2.createElement("div", { className: "w-full space-y-4" }, /* @__PURE__ */ React2.createElement(
    "div",
    {
      className: containerClasses,
      onDragOver: handleDragOver,
      onDragLeave: handleDragLeave,
      onDrop: handleDrop,
      onClick: handleClick
    },
    /* @__PURE__ */ React2.createElement("div", { className: uploadAreaClasses }, /* @__PURE__ */ React2.createElement(
      Upload,
      {
        className: clsx("mx-auto mb-4 text-gray-400", mode === "compact" ? "w-8 h-8 mb-2" : "w-12 h-12")
      }
    ), mode === "compact" ? /* @__PURE__ */ React2.createElement("p", { className: "text-sm text-gray-600 dark:text-gray-400" }, "\u70B9\u51FB\u4E0A\u4F20\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u8FD9\u91CC") : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("h3", { className: "text-lg font-semibold text-gray-700 dark:text-gray-300 mb-2" }, "\u4E0A\u4F20\u6587\u4EF6"), /* @__PURE__ */ React2.createElement("p", { className: "text-gray-600 dark:text-gray-400 mb-2" }, "\u70B9\u51FB\u9009\u62E9\u6587\u4EF6\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u8FD9\u91CC"), mode === "detailed" && /* @__PURE__ */ React2.createElement("div", { className: "text-sm text-gray-500 space-y-1" }, acceptedTypes.length > 0 && /* @__PURE__ */ React2.createElement("p", null, "\u652F\u6301\u683C\u5F0F: ", acceptedTypes.join(", ")), /* @__PURE__ */ React2.createElement("p", null, "\u6700\u5927\u5927\u5C0F: ", maxFileSize, "MB | \u6700\u591A\u6587\u4EF6: ", maxFiles, "\u4E2A")))),
    /* @__PURE__ */ React2.createElement(
      "input",
      {
        ref: fileInputRef,
        type: "file",
        multiple,
        accept: acceptedTypes.join(","),
        onChange: handleInputChange,
        className: "hidden",
        disabled
      }
    )
  ), uploadingFiles.length > 0 && /* @__PURE__ */ React2.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2.createElement("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u4E0A\u4F20\u4E2D (", uploadingFiles.length, ")"), uploadingFiles.map((uploadingFile) => /* @__PURE__ */ React2.createElement(
    "div",
    {
      key: uploadingFile.id,
      className: "flex items-center space-x-3 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg"
    },
    /* @__PURE__ */ React2.createElement("div", { className: "flex-shrink-0" }, uploadingFile.progress.status === "failed" ? /* @__PURE__ */ React2.createElement(AlertCircle, { className: "w-5 h-5 text-red-500" }) : uploadingFile.progress.status === "completed" ? /* @__PURE__ */ React2.createElement(CheckCircle2, { className: "w-5 h-5 text-green-500" }) : /* @__PURE__ */ React2.createElement(Loader2, { className: "w-5 h-5 text-blue-500 animate-spin" })),
    /* @__PURE__ */ React2.createElement("div", { className: "flex-grow min-w-0" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between mb-1" }, /* @__PURE__ */ React2.createElement("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 truncate" }, uploadingFile.file.name), /* @__PURE__ */ React2.createElement("span", { className: "text-xs text-gray-500" }, formatFileSize2(uploadingFile.file.size))), uploadingFile.error ? /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-red-500" }, uploadingFile.error) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { className: "w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2 mb-1" }, /* @__PURE__ */ React2.createElement(
      "div",
      {
        className: "bg-blue-500 h-2 rounded-full transition-all duration-300",
        style: { width: uploadingFile.progress.progress + "%" }
      }
    )), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-gray-500" }, formatProgress(uploadingFile.progress)))),
    /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: (e) => {
          e.stopPropagation();
          removeUploadingFile(uploadingFile.id);
        },
        className: "flex-shrink-0 p-1 text-gray-400 hover:text-red-500 transition-colors"
      },
      /* @__PURE__ */ React2.createElement(X, { className: "w-4 h-4" })
    )
  ))), completedFiles.length > 0 && /* @__PURE__ */ React2.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2.createElement("h4", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "\u5DF2\u5B8C\u6210 (", completedFiles.length, ")"), completedFiles.map((file) => /* @__PURE__ */ React2.createElement(
    "div",
    {
      key: file.id,
      className: "flex items-center space-x-3 p-3 bg-green-50 dark:bg-green-900/20 rounded-lg"
    },
    /* @__PURE__ */ React2.createElement("div", { className: "flex-shrink-0" }, getFileIcon(file.mimeType)),
    /* @__PURE__ */ React2.createElement("div", { className: "flex-grow min-w-0" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between mb-1" }, /* @__PURE__ */ React2.createElement("p", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 truncate" }, file.originalName), /* @__PURE__ */ React2.createElement("span", { className: "text-xs text-gray-500" }, formatFileSize2(file.size))), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-green-600 dark:text-green-400" }, "\u4E0A\u4F20\u6210\u529F \u2022 ", new Date(file.uploadTime).toLocaleTimeString())),
    /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: (e) => {
          e.stopPropagation();
          removeCompletedFile(file.id);
        },
        className: "flex-shrink-0 p-1 text-gray-400 hover:text-red-500 transition-colors"
      },
      /* @__PURE__ */ React2.createElement(X, { className: "w-4 h-4" })
    )
  ))), mode === "detailed" && (completedFiles.length > 0 || uploadingFiles.length > 0) && /* @__PURE__ */ React2.createElement("div", { className: "flex justify-between items-center text-sm text-gray-500 pt-2 border-t border-gray-200 dark:border-gray-700" }, /* @__PURE__ */ React2.createElement("span", null, "\u603B\u8BA1: ", completedFiles.length + uploadingFiles.length, " \u6587\u4EF6"), /* @__PURE__ */ React2.createElement("span", null, "\u5927\u5C0F:", " ", formatFileSize2(
    [
      ...completedFiles.map((f) => f.size),
      ...uploadingFiles.map((f) => f.file.size)
    ].reduce((total, size) => total + size, 0)
  ))));
};
var MIME_TYPE_CATEGORIES = {
  "image": ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"],
  "video": ["video/mp4", "video/avi", "video/mov", "video/webm"],
  "audio": ["audio/mp3", "audio/wav", "audio/ogg", "audio/aac"],
  "document": ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
  "archive": ["application/zip", "application/x-rar-compressed", "application/x-7z-compressed"]
};
var UniversalFileManager = ({
  moduleId,
  businessId,
  mode = "grid",
  allowUpload = true,
  allowDownload = true,
  allowDelete = false,
  allowBatch = true,
  showPreview = true,
  showSearch = true,
  showFilters = true,
  pageSize = 20,
  customActions = [],
  onFileSelect,
  onUploadComplete
}) => {
  const [state, setState] = useState({
    files: [],
    selectedFiles: /* @__PURE__ */ new Set(),
    loading: false,
    uploading: false,
    error: null,
    searchQuery: "",
    filters: {
      mimeType: "",
      dateRange: { start: null, end: null },
      sizeRange: { min: 0, max: Number.MAX_SAFE_INTEGER }
    },
    sortBy: "uploadTime",
    sortOrder: "desc",
    pagination: {
      page: 1,
      pageSize,
      total: 0,
      totalPages: 0
    },
    previewFile: null,
    showUploadModal: false
  });
  const loadFiles = useCallback(async () => {
    setState((prev) => ({ ...prev, loading: true, error: null }));
    try {
      const queryOptions = {
        moduleId,
        businessId,
        page: state.pagination.page,
        pageSize: state.pagination.pageSize,
        sortBy: state.sortBy,
        sortOrder: state.sortOrder
      };
      if (state.searchQuery) {
      }
      if (state.filters.mimeType) {
        queryOptions.mimeType = state.filters.mimeType;
      }
      if (state.filters.dateRange.start) {
        queryOptions.startTime = state.filters.dateRange.start;
      }
      if (state.filters.dateRange.end) {
        queryOptions.endTime = state.filters.dateRange.end;
      }
      const mockResult = {
        items: [],
        total: 0,
        page: queryOptions.page || 1,
        pageSize: queryOptions.pageSize || 20,
        totalPages: 0,
        hasNext: false,
        hasPrev: false
      };
      setState((prev) => ({
        ...prev,
        files: mockResult.items,
        pagination: {
          page: mockResult.page,
          pageSize: mockResult.pageSize,
          total: mockResult.total,
          totalPages: mockResult.totalPages
        },
        loading: false
      }));
    } catch (error) {
      console.error("\u52A0\u8F7D\u6587\u4EF6\u5217\u8868\u5931\u8D25:", error);
      setState((prev) => ({
        ...prev,
        loading: false,
        error: error instanceof Error ? error.message : "\u52A0\u8F7D\u6587\u4EF6\u5217\u8868\u5931\u8D25"
      }));
    }
  }, [moduleId, businessId, state.searchQuery, state.filters, state.sortBy, state.sortOrder, state.pagination.page, state.pagination.pageSize]);
  useEffect(() => {
    loadFiles();
  }, [loadFiles]);
  const handleFileSelect = useCallback((fileId, selected) => {
    setState((prev) => {
      const newSelectedFiles = new Set(prev.selectedFiles);
      if (selected) {
        newSelectedFiles.add(fileId);
      } else {
        newSelectedFiles.delete(fileId);
      }
      const selectedFileList = prev.files.filter((file) => newSelectedFiles.has(file.id));
      if (onFileSelect) {
        onFileSelect(selectedFileList);
      }
      return {
        ...prev,
        selectedFiles: newSelectedFiles
      };
    });
  }, [onFileSelect, state.files]);
  const handleSelectAll = useCallback((selected) => {
    setState((prev) => {
      const newSelectedFiles = selected ? new Set(prev.files.map((file) => file.id)) : /* @__PURE__ */ new Set();
      const selectedFileList = selected ? prev.files : [];
      if (onFileSelect) {
        onFileSelect(selectedFileList);
      }
      return {
        ...prev,
        selectedFiles: newSelectedFiles
      };
    });
  }, [onFileSelect, state.files]);
  const handleDeleteFiles = useCallback(async (fileIds) => {
    if (!window.confirm("\u786E\u5B9A\u8981\u5220\u9664\u9009\u4E2D\u7684 " + fileIds.length + " \u4E2A\u6587\u4EF6\u5417\uFF1F")) {
      return;
    }
    setState((prev) => ({ ...prev, loading: true }));
    try {
      console.log("\u5220\u9664\u6587\u4EF6:", fileIds);
      await loadFiles();
      setState((prev) => ({
        ...prev,
        selectedFiles: /* @__PURE__ */ new Set(),
        loading: false
      }));
    } catch (error) {
      console.error("\u5220\u9664\u6587\u4EF6\u5931\u8D25:", error);
      setState((prev) => ({
        ...prev,
        loading: false,
        error: error instanceof Error ? error.message : "\u5220\u9664\u6587\u4EF6\u5931\u8D25"
      }));
    }
  }, [loadFiles]);
  const handleDownloadFile = useCallback(async (file) => {
    try {
      console.log("\u4E0B\u8F7D\u6587\u4EF6:", file.originalName);
    } catch (error) {
      console.error("\u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25:", error);
      setState((prev) => ({
        ...prev,
        error: error instanceof Error ? error.message : "\u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25"
      }));
    }
  }, []);
  const handlePreviewFile = useCallback((file) => {
    setState((prev) => ({
      ...prev,
      previewFile: file
    }));
  }, []);
  const handleClosePreview = useCallback(() => {
    setState((prev) => ({
      ...prev,
      previewFile: null
    }));
  }, []);
  const handleSearch = useCallback((query) => {
    setState((prev) => ({
      ...prev,
      searchQuery: query,
      pagination: { ...prev.pagination, page: 1 }
    }));
  }, []);
  const handleFilterChange = useCallback((filterType, value) => {
    setState((prev) => ({
      ...prev,
      filters: {
        ...prev.filters,
        [filterType]: value
      },
      pagination: { ...prev.pagination, page: 1 }
    }));
  }, []);
  useCallback((field) => {
    setState((prev) => ({
      ...prev,
      sortBy: field,
      sortOrder: prev.sortBy === field && prev.sortOrder === "asc" ? "desc" : "asc",
      pagination: { ...prev.pagination, page: 1 }
    }));
  }, []);
  const handlePageChange = useCallback((page) => {
    setState((prev) => ({
      ...prev,
      pagination: { ...prev.pagination, page }
    }));
  }, []);
  const formatFileSize2 = useCallback((bytes) => {
    if (bytes === 0) return "0 B";
    const k = 1024;
    const sizes = ["B", "KB", "MB", "GB", "TB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  }, []);
  const getFileTypeIcon = useCallback((mimeType) => {
    if (mimeType.startsWith("image/")) return "\u{1F5BC}\uFE0F";
    if (mimeType.startsWith("video/")) return "\u{1F3AC}";
    if (mimeType.startsWith("audio/")) return "\u{1F3B5}";
    if (mimeType.includes("pdf")) return "\u{1F4C4}";
    if (mimeType.includes("word")) return "\u{1F4DD}";
    if (mimeType.includes("excel")) return "\u{1F4CA}";
    if (mimeType.includes("powerpoint")) return "\u{1F4CA}";
    if (mimeType.includes("zip") || mimeType.includes("rar")) return "\u{1F4E6}";
    return "\u{1F4C1}";
  }, []);
  const getFileTypeLabel = useCallback((mimeType) => {
    for (const [category, types] of Object.entries(MIME_TYPE_CATEGORIES)) {
      if (types.some((type) => mimeType.includes(type))) {
        return category;
      }
    }
    return "other";
  }, []);
  const isPreviewable = useCallback((file) => {
    return file.mimeType.startsWith("image/") || file.mimeType.startsWith("video/") || file.mimeType.startsWith("audio/") || file.mimeType.includes("pdf");
  }, []);
  const renderFileItem = useCallback((file) => {
    const isSelected = state.selectedFiles.has(file.id);
    const typeIcon = getFileTypeIcon(file.mimeType);
    const typeLabel = getFileTypeLabel(file.mimeType);
    return /* @__PURE__ */ React2.createElement(
      "div",
      {
        key: file.id,
        className: clsx("relative border rounded-lg p-4 cursor-pointer transition-all duration-200 hover:shadow-md", isSelected ? "border-blue-500 bg-blue-50" : "border-gray-200 hover:border-gray-300"),
        onClick: () => handleFileSelect(file.id, !isSelected)
      },
      allowBatch && /* @__PURE__ */ React2.createElement("div", { className: "absolute top-2 left-2" }, /* @__PURE__ */ React2.createElement(
        "input",
        {
          type: "checkbox",
          checked: isSelected,
          onChange: (e) => {
            e.stopPropagation();
            handleFileSelect(file.id, e.target.checked);
          },
          className: "w-4 h-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500"
        }
      )),
      /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col items-center space-y-2" }, /* @__PURE__ */ React2.createElement("div", { className: "text-4xl" }, typeIcon), /* @__PURE__ */ React2.createElement("div", { className: "text-center w-full" }, /* @__PURE__ */ React2.createElement("h3", { className: "font-medium text-sm text-gray-900 truncate", title: file.originalName }, file.originalName), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-gray-500 mt-1" }, formatFileSize2(file.size)), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-blue-600 capitalize" }, typeLabel), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-gray-400" }, new Date(file.uploadTime).toLocaleDateString()))),
      /* @__PURE__ */ React2.createElement("div", { className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity" }, /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-1" }, showPreview && isPreviewable(file) && /* @__PURE__ */ React2.createElement(
        "button",
        {
          onClick: (e) => {
            e.stopPropagation();
            handlePreviewFile(file);
          },
          className: "p-1 text-gray-600 hover:text-blue-600 hover:bg-white rounded",
          title: "\u9884\u89C8"
        },
        "\u{1F441}\uFE0F"
      ), allowDownload && /* @__PURE__ */ React2.createElement(
        "button",
        {
          onClick: (e) => {
            e.stopPropagation();
            handleDownloadFile(file);
          },
          className: "p-1 text-gray-600 hover:text-green-600 hover:bg-white rounded",
          title: "\u4E0B\u8F7D"
        },
        "\u2B07\uFE0F"
      ), allowDelete && /* @__PURE__ */ React2.createElement(
        "button",
        {
          onClick: (e) => {
            e.stopPropagation();
            handleDeleteFiles([file.id]);
          },
          className: "p-1 text-gray-600 hover:text-red-600 hover:bg-white rounded",
          title: "\u5220\u9664"
        },
        "\u{1F5D1}\uFE0F"
      )))
    );
  }, [
    state.selectedFiles,
    allowBatch,
    allowDownload,
    allowDelete,
    showPreview,
    handleFileSelect,
    handlePreviewFile,
    handleDownloadFile,
    handleDeleteFiles,
    getFileTypeIcon,
    getFileTypeLabel,
    formatFileSize2,
    isPreviewable
  ]);
  const renderSearchBar = () => {
    if (!showSearch) return null;
    return /* @__PURE__ */ React2.createElement("div", { className: "mb-6" }, /* @__PURE__ */ React2.createElement("div", { className: "relative" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "text",
        placeholder: "\u641C\u7D22\u6587\u4EF6\u540D...",
        value: state.searchQuery,
        onChange: (e) => handleSearch(e.target.value),
        className: "w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
      }
    ), /* @__PURE__ */ React2.createElement("div", { className: "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" }, /* @__PURE__ */ React2.createElement("span", { className: "text-gray-400" }, "\u{1F50D}"))));
  };
  const renderFilters = () => {
    if (!showFilters) return null;
    return /* @__PURE__ */ React2.createElement("div", { className: "mb-6 p-4 bg-gray-50 rounded-lg" }, /* @__PURE__ */ React2.createElement("h3", { className: "text-sm font-medium text-gray-700 mb-3" }, "\u7B5B\u9009\u5668"), /* @__PURE__ */ React2.createElement("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-xs font-medium text-gray-700 mb-1" }, "\u6587\u4EF6\u7C7B\u578B"), /* @__PURE__ */ React2.createElement(
      "select",
      {
        value: state.filters.mimeType,
        onChange: (e) => handleFilterChange("mimeType", e.target.value),
        className: "w-full px-3 py-2 text-sm border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
      },
      /* @__PURE__ */ React2.createElement("option", { value: "" }, "\u5168\u90E8"),
      /* @__PURE__ */ React2.createElement("option", { value: "image/" }, "\u56FE\u7247"),
      /* @__PURE__ */ React2.createElement("option", { value: "video/" }, "\u89C6\u9891"),
      /* @__PURE__ */ React2.createElement("option", { value: "audio/" }, "\u97F3\u9891"),
      /* @__PURE__ */ React2.createElement("option", { value: "application/pdf" }, "PDF"),
      /* @__PURE__ */ React2.createElement("option", { value: "application/" }, "\u6587\u6863")
    )), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-xs font-medium text-gray-700 mb-1" }, "\u4E0A\u4F20\u65F6\u95F4"), /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "date",
        value: state.filters.dateRange.start?.toISOString().split("T")[0] || "",
        onChange: (e) => handleFilterChange("dateRange", {
          ...state.filters.dateRange,
          start: e.target.value ? new Date(e.target.value) : null
        }),
        className: "flex-1 px-2 py-1 text-xs border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
      }
    ), /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "date",
        value: state.filters.dateRange.end?.toISOString().split("T")[0] || "",
        onChange: (e) => handleFilterChange("dateRange", {
          ...state.filters.dateRange,
          end: e.target.value ? new Date(e.target.value) : null
        }),
        className: "flex-1 px-2 py-1 text-xs border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
      }
    ))), /* @__PURE__ */ React2.createElement("div", { className: "flex items-end" }, /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => setState((prev) => ({
          ...prev,
          filters: {
            mimeType: "",
            dateRange: { start: null, end: null },
            sizeRange: { min: 0, max: Number.MAX_SAFE_INTEGER }
          }
        })),
        className: "px-3 py-2 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50"
      },
      "\u6E05\u9664\u7B5B\u9009"
    ))));
  };
  const renderToolbar = () => {
    const selectedCount = state.selectedFiles.size;
    const hasSelection = selectedCount > 0;
    return /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between mb-6" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-4" }, allowBatch && state.files.length > 0 && /* @__PURE__ */ React2.createElement("label", { className: "flex items-center space-x-2" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "checkbox",
        checked: selectedCount === state.files.length && state.files.length > 0,
        onChange: (e) => handleSelectAll(e.target.checked),
        className: "w-4 h-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500"
      }
    ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm text-gray-700" }, "\u5168\u9009 (", selectedCount, "/", state.files.length, ")")), hasSelection && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-2" }, allowDelete && /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => handleDeleteFiles(Array.from(state.selectedFiles)),
        className: "px-3 py-1 text-sm text-red-600 border border-red-300 rounded hover:bg-red-50"
      },
      "\u5220\u9664\u9009\u4E2D (",
      selectedCount,
      ")"
    ), customActions.map((action) => {
      const selectedFileList = state.files.filter((file) => state.selectedFiles.has(file.id));
      const isDisabled = action.disabled?.(selectedFileList) || false;
      return /* @__PURE__ */ React2.createElement(
        "button",
        {
          key: action.key,
          onClick: () => action.onClick(selectedFileList),
          disabled: isDisabled,
          className: clsx("px-3 py-1 text-sm border rounded", isDisabled ? "text-gray-400 border-gray-200 cursor-not-allowed" : "text-blue-600 border-blue-300 hover:bg-blue-50")
        },
        action.icon && /* @__PURE__ */ React2.createElement("span", { className: "mr-1" }, action.icon),
        action.label
      );
    }))), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-4" }, /* @__PURE__ */ React2.createElement(
      "select",
      {
        value: state.sortBy + "-" + state.sortOrder,
        onChange: (e) => {
          const [sortBy, sortOrder] = e.target.value.split("-");
          setState((prev) => ({ ...prev, sortBy, sortOrder }));
        },
        className: "px-3 py-1 text-sm border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
      },
      /* @__PURE__ */ React2.createElement("option", { value: "uploadTime-desc" }, "\u6700\u65B0\u4E0A\u4F20"),
      /* @__PURE__ */ React2.createElement("option", { value: "uploadTime-asc" }, "\u6700\u65E9\u4E0A\u4F20"),
      /* @__PURE__ */ React2.createElement("option", { value: "originalName-asc" }, "\u6587\u4EF6\u540D A-Z"),
      /* @__PURE__ */ React2.createElement("option", { value: "originalName-desc" }, "\u6587\u4EF6\u540D Z-A"),
      /* @__PURE__ */ React2.createElement("option", { value: "size-desc" }, "\u6587\u4EF6\u5927\u5C0F \u5927-\u5C0F"),
      /* @__PURE__ */ React2.createElement("option", { value: "size-asc" }, "\u6587\u4EF6\u5927\u5C0F \u5C0F-\u5927")
    ), allowUpload && /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => setState((prev) => ({ ...prev, showUploadModal: true })),
        className: "px-4 py-2 text-sm text-white bg-blue-600 rounded hover:bg-blue-700 focus:ring-2 focus:ring-blue-500"
      },
      "\u2B06\uFE0F \u4E0A\u4F20\u6587\u4EF6"
    )));
  };
  const renderPagination = () => {
    if (state.pagination.totalPages <= 1) return null;
    const { page, totalPages } = state.pagination;
    const pages = [];
    const startPage = Math.max(1, page - 2);
    const endPage = Math.min(totalPages, page + 2);
    for (let i = startPage; i <= endPage; i++) {
      pages.push(i);
    }
    return /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between mt-6" }, /* @__PURE__ */ React2.createElement("div", { className: "text-sm text-gray-700" }, "\u663E\u793A\u7B2C ", (page - 1) * state.pagination.pageSize + 1, " - ", Math.min(page * state.pagination.pageSize, state.pagination.total), " \u9879\uFF0C \u5171 ", state.pagination.total, " \u9879"), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-2" }, /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => handlePageChange(page - 1),
        disabled: page <= 1,
        className: "px-3 py-1 text-sm border rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50"
      },
      "\u4E0A\u4E00\u9875"
    ), pages.map((pageNum) => /* @__PURE__ */ React2.createElement(
      "button",
      {
        key: pageNum,
        onClick: () => handlePageChange(pageNum),
        className: clsx("px-3 py-1 text-sm border rounded", pageNum === page ? "bg-blue-600 text-white border-blue-600" : "hover:bg-gray-50")
      },
      pageNum
    )), /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => handlePageChange(page + 1),
        disabled: page >= totalPages,
        className: "px-3 py-1 text-sm border rounded disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50"
      },
      "\u4E0B\u4E00\u9875"
    )));
  };
  return /* @__PURE__ */ React2.createElement("div", { className: "w-full" }, state.error && /* @__PURE__ */ React2.createElement("div", { className: "mb-4 p-4 bg-red-50 border border-red-200 rounded-lg" }, /* @__PURE__ */ React2.createElement("p", { className: "text-red-800" }, state.error), /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: () => setState((prev) => ({ ...prev, error: null })),
      className: "mt-2 text-red-600 hover:text-red-800"
    },
    "\u5173\u95ED"
  )), renderSearchBar(), renderFilters(), renderToolbar(), /* @__PURE__ */ React2.createElement("div", { className: "min-h-96" }, state.loading ? /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-center h-32" }, /* @__PURE__ */ React2.createElement("div", { className: "text-gray-500" }, /* @__PURE__ */ React2.createElement("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-2" }), /* @__PURE__ */ React2.createElement("p", null, "\u52A0\u8F7D\u4E2D..."))) : state.files.length === 0 ? /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-center h-32" }, /* @__PURE__ */ React2.createElement("div", { className: "text-center text-gray-500" }, /* @__PURE__ */ React2.createElement("p", { className: "text-4xl mb-2" }, "\u{1F4C1}"), /* @__PURE__ */ React2.createElement("p", null, "\u6682\u65E0\u6587\u4EF6"), allowUpload && /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: () => setState((prev) => ({ ...prev, showUploadModal: true })),
      className: "mt-2 text-blue-600 hover:text-blue-800"
    },
    "\u70B9\u51FB\u4E0A\u4F20\u7B2C\u4E00\u4E2A\u6587\u4EF6"
  ))) : /* @__PURE__ */ React2.createElement("div", { className: clsx("grid gap-4", mode === "grid" ? "grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6" : "grid-cols-1") }, state.files.map(renderFileItem))), renderPagination(), state.previewFile && showPreview && /* @__PURE__ */ React2.createElement(
    FilePreviewModal,
    {
      file: state.previewFile,
      onClose: handleClosePreview
    }
  ), state.showUploadModal && allowUpload && /* @__PURE__ */ React2.createElement(
    UploadModal,
    {
      moduleId,
      businessId,
      onClose: () => setState((prev) => ({ ...prev, showUploadModal: false })),
      onUploadComplete: (files) => {
        setState((prev) => ({ ...prev, showUploadModal: false }));
        if (onUploadComplete) {
          onUploadComplete(files);
        }
        loadFiles();
      }
    }
  ));
};
var FilePreviewModal = ({ file, onClose }) => {
  const renderPreviewContent = () => {
    if (file.mimeType.startsWith("image/")) {
      return /* @__PURE__ */ React2.createElement(
        "img",
        {
          src: file.cdnUrl || "/api/files/" + file.id + "/download",
          alt: file.originalName,
          className: "max-w-full max-h-full object-contain"
        }
      );
    }
    if (file.mimeType.startsWith("video/")) {
      return /* @__PURE__ */ React2.createElement(
        "video",
        {
          src: file.cdnUrl || "/api/files/" + file.id + "/download",
          controls: true,
          className: "max-w-full max-h-full"
        },
        "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u89C6\u9891\u64AD\u653E"
      );
    }
    if (file.mimeType.startsWith("audio/")) {
      return /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col items-center space-y-4" }, /* @__PURE__ */ React2.createElement("div", { className: "text-6xl" }, "\u{1F3B5}"), /* @__PURE__ */ React2.createElement(
        "audio",
        {
          src: file.cdnUrl || "/api/files/" + file.id + "/download",
          controls: true,
          className: "w-full max-w-md"
        },
        "\u60A8\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301\u97F3\u9891\u64AD\u653E"
      ));
    }
    if (file.mimeType.includes("pdf")) {
      return /* @__PURE__ */ React2.createElement(
        "iframe",
        {
          src: (file.cdnUrl || "/api/files/" + file.id + "/download") + "#toolbar=0",
          className: "w-full h-full min-h-96",
          title: file.originalName
        }
      );
    }
    return /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col items-center justify-center h-64 text-gray-500" }, /* @__PURE__ */ React2.createElement("div", { className: "text-4xl mb-4" }, "\u{1F4C4}"), /* @__PURE__ */ React2.createElement("p", null, "\u6B64\u6587\u4EF6\u7C7B\u578B\u6682\u4E0D\u652F\u6301\u9884\u89C8"), /* @__PURE__ */ React2.createElement(
      "a",
      {
        href: file.cdnUrl || "/api/files/" + file.id + "/download",
        download: file.originalName,
        className: "mt-4 px-4 py-2 text-blue-600 border border-blue-300 rounded hover:bg-blue-50"
      },
      "\u4E0B\u8F7D\u6587\u4EF6"
    ));
  };
  return /* @__PURE__ */ React2.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50" }, /* @__PURE__ */ React2.createElement("div", { className: "bg-white rounded-lg max-w-4xl max-h-[90vh] overflow-hidden flex flex-col" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between p-4 border-b" }, /* @__PURE__ */ React2.createElement("h2", { className: "text-lg font-medium truncate", title: file.originalName }, file.originalName), /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: onClose,
      className: "p-2 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100"
    },
    "\u2715"
  )), /* @__PURE__ */ React2.createElement("div", { className: "flex-1 p-4 overflow-auto flex items-center justify-center" }, renderPreviewContent()), /* @__PURE__ */ React2.createElement("div", { className: "p-4 border-t bg-gray-50 text-sm text-gray-600" }, /* @__PURE__ */ React2.createElement("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u6587\u4EF6\u5927\u5C0F\uFF1A"), (file.size / 1024 / 1024).toFixed(2), " MB"), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u4E0A\u4F20\u65F6\u95F4\uFF1A"), new Date(file.uploadTime).toLocaleString()), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u6587\u4EF6\u7C7B\u578B\uFF1A"), file.mimeType), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u8BBF\u95EE\u6B21\u6570\uFF1A"), file.accessCount)))));
};
var UploadModal = ({
  moduleId,
  businessId,
  onClose,
  onUploadComplete
}) => {
  return /* @__PURE__ */ React2.createElement("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50" }, /* @__PURE__ */ React2.createElement("div", { className: "bg-white rounded-lg max-w-2xl w-full max-h-[80vh] overflow-hidden" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between p-4 border-b" }, /* @__PURE__ */ React2.createElement("h2", { className: "text-lg font-medium" }, "\u4E0A\u4F20\u6587\u4EF6"), /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: onClose,
      className: "p-2 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100"
    },
    "\u2715"
  )), /* @__PURE__ */ React2.createElement("div", { className: "p-6" }, /* @__PURE__ */ React2.createElement("p", { className: "text-gray-600 mb-4" }, "\u8FD9\u91CC\u5C06\u96C6\u6210UniversalFileUploader\u7EC4\u4EF6"), /* @__PURE__ */ React2.createElement("div", { className: "border-2 border-dashed border-gray-300 rounded-lg p-8 text-center text-gray-500" }, /* @__PURE__ */ React2.createElement("div", { className: "text-4xl mb-4" }, "\u{1F4C1}"), /* @__PURE__ */ React2.createElement("p", null, "\u62D6\u62FD\u6587\u4EF6\u5230\u6B64\u5904\u6216\u70B9\u51FB\u9009\u62E9\u6587\u4EF6"), /* @__PURE__ */ React2.createElement(
    "input",
    {
      type: "file",
      multiple: true,
      className: "hidden",
      onChange: (e) => {
        console.log("\u9009\u62E9\u6587\u4EF6:", e.target.files);
        onUploadComplete([]);
      }
    }
  )))));
};
var FolderManager = ({
  currentFolderId,
  folderTree,
  showFileCount = true,
  showSize = true,
  allowCreate = true,
  allowRename = true,
  allowDelete = true,
  allowDrag = false,
  onFolderSelect,
  onFolderCreate,
  onFolderRename,
  onFolderDelete,
  onFileMove
}) => {
  const [state, setState] = useState({
    expandedFolders: new Set(currentFolderId ? [currentFolderId] : []),
    editingFolder: null,
    editingName: "",
    creatingFolder: null,
    newFolderName: "",
    dragOverFolder: null,
    contextMenu: null
  });
  const toggleFolder = useCallback((folderId) => {
    setState((prev) => {
      const newExpanded = new Set(prev.expandedFolders);
      if (newExpanded.has(folderId)) {
        newExpanded.delete(folderId);
      } else {
        newExpanded.add(folderId);
      }
      return { ...prev, expandedFolders: newExpanded };
    });
  }, []);
  const selectFolder = useCallback((folderId) => {
    if (onFolderSelect) {
      onFolderSelect(folderId);
    }
  }, [onFolderSelect]);
  const startCreateFolder = useCallback((parentId) => {
    setState((prev) => ({
      ...prev,
      creatingFolder: parentId || null,
      newFolderName: "\u65B0\u5EFA\u6587\u4EF6\u5939",
      contextMenu: null
    }));
  }, []);
  const confirmCreateFolder = useCallback(async () => {
    if (!state.newFolderName.trim() || !onFolderCreate) return;
    try {
      await onFolderCreate(state.creatingFolder || void 0, state.newFolderName.trim());
      setState((prev) => ({
        ...prev,
        creatingFolder: null,
        newFolderName: ""
      }));
    } catch (error) {
      console.error("\u521B\u5EFA\u6587\u4EF6\u5939\u5931\u8D25:", error);
    }
  }, [state.creatingFolder, state.newFolderName, onFolderCreate]);
  const cancelCreateFolder = useCallback(() => {
    setState((prev) => ({
      ...prev,
      creatingFolder: null,
      newFolderName: ""
    }));
  }, []);
  const startRenameFolder = useCallback((folderId, currentName) => {
    setState((prev) => ({
      ...prev,
      editingFolder: folderId,
      editingName: currentName,
      contextMenu: null
    }));
  }, []);
  const confirmRenameFolder = useCallback(async () => {
    if (!state.editingFolder || !state.editingName.trim() || !onFolderRename) return;
    try {
      await onFolderRename(state.editingFolder, state.editingName.trim());
      setState((prev) => ({
        ...prev,
        editingFolder: null,
        editingName: ""
      }));
    } catch (error) {
      console.error("\u91CD\u547D\u540D\u6587\u4EF6\u5939\u5931\u8D25:", error);
    }
  }, [state.editingFolder, state.editingName, onFolderRename]);
  const cancelRenameFolder = useCallback(() => {
    setState((prev) => ({
      ...prev,
      editingFolder: null,
      editingName: ""
    }));
  }, []);
  const deleteFolder = useCallback(async (folderId, folderName) => {
    if (!window.confirm('\u786E\u5B9A\u8981\u5220\u9664\u6587\u4EF6\u5939"' + folderName + '"\u5417\uFF1F\u6B64\u64CD\u4F5C\u5C06\u5220\u9664\u6587\u4EF6\u5939\u5185\u7684\u6240\u6709\u6587\u4EF6\u3002')) {
      return;
    }
    if (!onFolderDelete) return;
    try {
      await onFolderDelete(folderId);
      setState((prev) => ({ ...prev, contextMenu: null }));
    } catch (error) {
      console.error("\u5220\u9664\u6587\u4EF6\u5939\u5931\u8D25:", error);
    }
  }, [onFolderDelete]);
  const handleContextMenu = useCallback((e, folderId) => {
    e.preventDefault();
    setState((prev) => ({
      ...prev,
      contextMenu: {
        folderId,
        x: e.clientX,
        y: e.clientY
      }
    }));
  }, []);
  const closeContextMenu = useCallback(() => {
    setState((prev) => ({ ...prev, contextMenu: null }));
  }, []);
  const handleDragOver = useCallback((e, folderId) => {
    if (!allowDrag) return;
    e.preventDefault();
    setState((prev) => ({ ...prev, dragOverFolder: folderId }));
  }, [allowDrag]);
  const handleDragLeave = useCallback(() => {
    setState((prev) => ({ ...prev, dragOverFolder: null }));
  }, []);
  const handleDrop = useCallback(async (e, folderId) => {
    if (!allowDrag || !onFileMove) return;
    e.preventDefault();
    setState((prev) => ({ ...prev, dragOverFolder: null }));
    try {
      const fileIds = JSON.parse(e.dataTransfer.getData("application/json"));
      await onFileMove(fileIds, folderId);
    } catch (error) {
      console.error("\u79FB\u52A8\u6587\u4EF6\u5931\u8D25:", error);
    }
  }, [allowDrag, onFileMove]);
  const formatSize = useCallback((bytes) => {
    if (bytes === 0) return "0 B";
    const k = 1024;
    const sizes = ["B", "KB", "MB", "GB", "TB"];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
  }, []);
  const renderFolderNode = useCallback((folder, level = 0) => {
    const isExpanded = state.expandedFolders.has(folder.id);
    const isSelected = currentFolderId === folder.id;
    const isEditing = state.editingFolder === folder.id;
    const isDragOver = state.dragOverFolder === folder.id;
    return /* @__PURE__ */ React2.createElement("div", { key: folder.id, className: "select-none" }, /* @__PURE__ */ React2.createElement(
      "div",
      {
        className: clsx("flex items-center py-1 px-2 rounded-md cursor-pointer transition-colors", isSelected ? "bg-blue-100 text-blue-800" : isDragOver ? "bg-green-100" : "hover:bg-gray-100"),
        style: { paddingLeft: level * 16 + 8 + "px" },
        onClick: () => selectFolder(folder.id),
        onContextMenu: (e) => handleContextMenu(e, folder.id),
        onDragOver: allowDrag ? (e) => handleDragOver(e, folder.id) : void 0,
        onDragLeave: allowDrag ? handleDragLeave : void 0,
        onDrop: allowDrag ? (e) => handleDrop(e, folder.id) : void 0
      },
      folder.children.length > 0 && /* @__PURE__ */ React2.createElement(
        "button",
        {
          onClick: (e) => {
            e.stopPropagation();
            toggleFolder(folder.id);
          },
          className: "mr-1 p-1 hover:bg-gray-200 rounded"
        },
        /* @__PURE__ */ React2.createElement("span", { className: clsx("text-xs transition-transform", isExpanded ? "rotate-90" : "") }, "\u25B6")
      ),
      /* @__PURE__ */ React2.createElement("span", { className: "mr-2 text-yellow-600" }, isExpanded ? "\u{1F4C2}" : "\u{1F4C1}"),
      /* @__PURE__ */ React2.createElement("div", { className: "flex-1 flex items-center justify-between" }, isEditing ? /* @__PURE__ */ React2.createElement(
        "input",
        {
          type: "text",
          value: state.editingName,
          onChange: (e) => setState((prev) => ({ ...prev, editingName: e.target.value })),
          onBlur: confirmRenameFolder,
          onKeyDown: (e) => {
            if (e.key === "Enter") {
              confirmRenameFolder();
            } else if (e.key === "Escape") {
              cancelRenameFolder();
            }
          },
          onClick: (e) => e.stopPropagation(),
          className: "flex-1 px-1 py-0 text-sm border rounded focus:outline-none focus:ring-1 focus:ring-blue-500",
          autoFocus: true
        }
      ) : /* @__PURE__ */ React2.createElement("span", { className: "text-sm truncate" }, folder.name), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-2 text-xs text-gray-500 ml-2" }, showFileCount && /* @__PURE__ */ React2.createElement("span", null, folder.fileCount, " \u9879"), showSize && folder.totalSize > 0 && /* @__PURE__ */ React2.createElement("span", null, formatSize(folder.totalSize))))
    ), state.creatingFolder === folder.id && /* @__PURE__ */ React2.createElement(
      "div",
      {
        className: "flex items-center py-1 px-2 ml-4",
        style: { paddingLeft: (level + 1) * 16 + 8 + "px" }
      },
      /* @__PURE__ */ React2.createElement("span", { className: "mr-2 text-yellow-600" }, "\u{1F4C1}"),
      /* @__PURE__ */ React2.createElement(
        "input",
        {
          type: "text",
          value: state.newFolderName,
          onChange: (e) => setState((prev) => ({ ...prev, newFolderName: e.target.value })),
          onBlur: confirmCreateFolder,
          onKeyDown: (e) => {
            if (e.key === "Enter") {
              confirmCreateFolder();
            } else if (e.key === "Escape") {
              cancelCreateFolder();
            }
          },
          className: "flex-1 px-1 py-0 text-sm border rounded focus:outline-none focus:ring-1 focus:ring-blue-500",
          autoFocus: true
        }
      )
    ), isExpanded && folder.children.map(
      (child) => renderFolderNode(child, level + 1)
    ));
  }, [
    state.expandedFolders,
    state.editingFolder,
    state.editingName,
    state.creatingFolder,
    state.newFolderName,
    state.dragOverFolder,
    currentFolderId,
    allowDrag,
    showFileCount,
    showSize,
    selectFolder,
    toggleFolder,
    handleContextMenu,
    handleDragOver,
    handleDragLeave,
    handleDrop,
    confirmRenameFolder,
    cancelRenameFolder,
    confirmCreateFolder,
    cancelCreateFolder,
    formatSize
  ]);
  const renderContextMenu = () => {
    if (!state.contextMenu) return null;
    const folder = findFolderById(folderTree, state.contextMenu.folderId);
    if (!folder) return null;
    return /* @__PURE__ */ React2.createElement(
      "div",
      {
        className: "fixed bg-white border border-gray-200 rounded-md shadow-lg z-[50] py-1",
        style: {
          left: state.contextMenu.x,
          top: state.contextMenu.y
        },
        onClick: closeContextMenu
      },
      allowCreate && /* @__PURE__ */ React2.createElement(
        "button",
        {
          onClick: () => startCreateFolder(folder.id),
          className: "w-full px-4 py-2 text-left text-sm hover:bg-gray-100 flex items-center"
        },
        /* @__PURE__ */ React2.createElement("span", { className: "mr-2" }, "\u{1F4C1}"),
        "\u65B0\u5EFA\u5B50\u6587\u4EF6\u5939"
      ),
      allowRename && /* @__PURE__ */ React2.createElement(
        "button",
        {
          onClick: () => startRenameFolder(folder.id, folder.name),
          className: "w-full px-4 py-2 text-left text-sm hover:bg-gray-100 flex items-center"
        },
        /* @__PURE__ */ React2.createElement("span", { className: "mr-2" }, "\u270F\uFE0F"),
        "\u91CD\u547D\u540D"
      ),
      allowDelete && /* @__PURE__ */ React2.createElement(
        "button",
        {
          onClick: () => deleteFolder(folder.id, folder.name),
          className: "w-full px-4 py-2 text-left text-sm hover:bg-gray-100 text-red-600 flex items-center"
        },
        /* @__PURE__ */ React2.createElement("span", { className: "mr-2" }, "\u{1F5D1}\uFE0F"),
        "\u5220\u9664\u6587\u4EF6\u5939"
      )
    );
  };
  const findFolderById = (folders, id) => {
    for (const folder of folders) {
      if (folder.id === id) return folder;
      const found = findFolderById(folder.children, id);
      if (found) return found;
    }
    return null;
  };
  React2.useEffect(() => {
    if (!state.contextMenu) return;
    const handleClickOutside = () => {
      closeContextMenu();
    };
    document.addEventListener("click", handleClickOutside);
    return () => document.removeEventListener("click", handleClickOutside);
  }, [state.contextMenu, closeContextMenu]);
  return /* @__PURE__ */ React2.createElement("div", { className: "relative" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between p-2 border-b bg-gray-50" }, /* @__PURE__ */ React2.createElement("h3", { className: "text-sm font-medium text-gray-700" }, "\u6587\u4EF6\u5939"), allowCreate && /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: () => startCreateFolder(),
      className: "px-2 py-1 text-xs text-blue-600 border border-blue-300 rounded hover:bg-blue-50",
      title: "\u65B0\u5EFA\u6587\u4EF6\u5939"
    },
    "\u2795"
  )), /* @__PURE__ */ React2.createElement("div", { className: "p-2 max-h-96 overflow-y-auto" }, folderTree.length === 0 ? /* @__PURE__ */ React2.createElement("div", { className: "text-center text-gray-500 py-8" }, /* @__PURE__ */ React2.createElement("div", { className: "text-2xl mb-2" }, "\u{1F4C1}"), /* @__PURE__ */ React2.createElement("p", { className: "text-sm" }, "\u6682\u65E0\u6587\u4EF6\u5939"), allowCreate && /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: () => startCreateFolder(),
      className: "mt-2 text-blue-600 hover:text-blue-800 text-sm"
    },
    "\u521B\u5EFA\u7B2C\u4E00\u4E2A\u6587\u4EF6\u5939"
  )) : /* @__PURE__ */ React2.createElement("div", { className: "space-y-1" }, folderTree.map((folder) => renderFolderNode(folder))), state.creatingFolder === null && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center py-1 px-2" }, /* @__PURE__ */ React2.createElement("span", { className: "mr-2 text-yellow-600" }, "\u{1F4C1}"), /* @__PURE__ */ React2.createElement(
    "input",
    {
      type: "text",
      value: state.newFolderName,
      onChange: (e) => setState((prev) => ({ ...prev, newFolderName: e.target.value })),
      onBlur: confirmCreateFolder,
      onKeyDown: (e) => {
        if (e.key === "Enter") {
          confirmCreateFolder();
        } else if (e.key === "Escape") {
          cancelCreateFolder();
        }
      },
      className: "flex-1 px-1 py-0 text-sm border rounded focus:outline-none focus:ring-1 focus:ring-blue-500",
      autoFocus: true
    }
  ))), renderContextMenu());
};
var FolderManager_default = FolderManager;
var FileShareModal = ({
  files,
  onClose,
  onShareSuccess
}) => {
  const [shareOptions, setShareOptions] = useState({
    expireType: "7days",
    requirePassword: false,
    password: "",
    permission: "view",
    downloadLimit: void 0
  });
  const [loading, setLoading] = useState(false);
  const [shareInfo, setShareInfo] = useState(null);
  const [error, setError] = useState(null);
  const generatePassword = useCallback(() => {
    const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    let password = "";
    for (let i = 0; i < 6; i++) {
      password += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    setShareOptions((prev) => ({ ...prev, password }));
  }, []);
  const getExpiresAt = useCallback(() => {
    const now = /* @__PURE__ */ new Date();
    switch (shareOptions.expireType) {
      case "never":
        return void 0;
      case "1hour":
        return new Date(now.getTime() + 60 * 60 * 1e3);
      case "1day":
        return new Date(now.getTime() + 24 * 60 * 60 * 1e3);
      case "7days":
        return new Date(now.getTime() + 7 * 24 * 60 * 60 * 1e3);
      case "30days":
        return new Date(now.getTime() + 30 * 24 * 60 * 60 * 1e3);
      case "custom":
        return shareOptions.customExpireTime;
      default:
        return void 0;
    }
  }, [shareOptions.expireType, shareOptions.customExpireTime]);
  const handleCreateShare = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const expiresAt = getExpiresAt();
      const mockShareInfo = {
        shareUrl: window.location.origin + "/share/" + generateShareCode(),
        password: shareOptions.requirePassword ? shareOptions.password : void 0,
        expiresAt,
        permission: shareOptions.permission,
        shareCode: generateShareCode()
      };
      setShareInfo(mockShareInfo);
      if (onShareSuccess) {
        onShareSuccess(mockShareInfo);
      }
    } catch (error2) {
      console.error("\u521B\u5EFA\u5206\u4EAB\u5931\u8D25:", error2);
      setError(error2 instanceof Error ? error2.message : "\u521B\u5EFA\u5206\u4EAB\u5931\u8D25");
    } finally {
      setLoading(false);
    }
  }, [files, shareOptions, getExpiresAt, onShareSuccess]);
  const generateShareCode = useCallback(() => {
    return Math.random().toString(36).substring(2, 10).toUpperCase();
  }, []);
  const copyToClipboard = useCallback(async (text) => {
    try {
      await navigator.clipboard.writeText(text);
      console.log("\u590D\u5236\u6210\u529F");
    } catch (error2) {
      console.error("\u590D\u5236\u5931\u8D25:", error2);
      const textArea = document.createElement("textarea");
      textArea.value = text;
      document.body.appendChild(textArea);
      textArea.select();
      document.execCommand("copy");
      document.body.removeChild(textArea);
    }
  }, []);
  const formatFileList = useCallback(() => {
    if (files.length === 0) return "0 \u4E2A\u6587\u4EF6";
    if (files.length === 1 && files[0]) {
      return files[0].originalName;
    }
    return files.length + " \u4E2A\u6587\u4EF6";
  }, [files]);
  const renderShareSettings = () => {
    if (shareInfo) return null;
    return /* @__PURE__ */ React2.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React2.createElement("div", { className: "bg-gray-50 p-4 rounded-lg" }, /* @__PURE__ */ React2.createElement("h3", { className: "font-medium text-gray-900 mb-2" }, "\u8981\u5206\u4EAB\u7684\u6587\u4EF6"), /* @__PURE__ */ React2.createElement("div", { className: "space-y-2" }, files.map((file) => /* @__PURE__ */ React2.createElement("div", { key: file.id, className: "flex items-center justify-between text-sm" }, /* @__PURE__ */ React2.createElement("span", { className: "text-gray-700 truncate" }, file.originalName), /* @__PURE__ */ React2.createElement("span", { className: "text-gray-500 text-xs" }, (file.size / 1024 / 1024).toFixed(2), " MB"))))), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u8FC7\u671F\u65F6\u95F4"), /* @__PURE__ */ React2.createElement(
      "select",
      {
        value: shareOptions.expireType,
        onChange: (e) => setShareOptions((prev) => ({
          ...prev,
          expireType: e.target.value
        })),
        className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
      },
      /* @__PURE__ */ React2.createElement("option", { value: "never" }, "\u6C38\u4E0D\u8FC7\u671F"),
      /* @__PURE__ */ React2.createElement("option", { value: "1hour" }, "1\u5C0F\u65F6\u540E"),
      /* @__PURE__ */ React2.createElement("option", { value: "1day" }, "1\u5929\u540E"),
      /* @__PURE__ */ React2.createElement("option", { value: "7days" }, "7\u5929\u540E"),
      /* @__PURE__ */ React2.createElement("option", { value: "30days" }, "30\u5929\u540E"),
      /* @__PURE__ */ React2.createElement("option", { value: "custom" }, "\u81EA\u5B9A\u4E49\u65F6\u95F4")
    ), shareOptions.expireType === "custom" && /* @__PURE__ */ React2.createElement("div", { className: "mt-2" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "datetime-local",
        value: shareOptions.customExpireTime?.toISOString().slice(0, 16) || "",
        onChange: (e) => setShareOptions((prev) => ({
          ...prev,
          customExpireTime: e.target.value ? new Date(e.target.value) : void 0
        })),
        className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500",
        min: (/* @__PURE__ */ new Date()).toISOString().slice(0, 16)
      }
    ))), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u8BBF\u95EE\u6743\u9650"), /* @__PURE__ */ React2.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React2.createElement("label", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "radio",
        name: "permission",
        value: "view",
        checked: shareOptions.permission === "view",
        onChange: (e) => setShareOptions((prev) => ({
          ...prev,
          permission: e.target.value
        })),
        className: "mr-2"
      }
    ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm" }, "\u4EC5\u9884\u89C8\uFF08\u4E0D\u5141\u8BB8\u4E0B\u8F7D\uFF09")), /* @__PURE__ */ React2.createElement("label", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "radio",
        name: "permission",
        value: "download",
        checked: shareOptions.permission === "download",
        onChange: (e) => setShareOptions((prev) => ({
          ...prev,
          permission: e.target.value
        })),
        className: "mr-2"
      }
    ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm" }, "\u5141\u8BB8\u4E0B\u8F7D")))), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "flex items-center mb-2" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "checkbox",
        checked: shareOptions.requirePassword,
        onChange: (e) => setShareOptions((prev) => ({
          ...prev,
          requirePassword: e.target.checked,
          password: e.target.checked ? prev.password : ""
        })),
        className: "mr-2"
      }
    ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm font-medium text-gray-700" }, "\u8BBE\u7F6E\u8BBF\u95EE\u5BC6\u7801")), shareOptions.requirePassword && /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "text",
        value: shareOptions.password,
        onChange: (e) => setShareOptions((prev) => ({
          ...prev,
          password: e.target.value
        })),
        placeholder: "\u8F93\u5165\u8BBF\u95EE\u5BC6\u7801",
        className: "flex-1 px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500",
        maxLength: 20
      }
    ), /* @__PURE__ */ React2.createElement(
      "button",
      {
        type: "button",
        onClick: generatePassword,
        className: "px-3 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50"
      },
      "\u968F\u673A\u751F\u6210"
    ))), shareOptions.permission === "download" && /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u4E0B\u8F7D\u6B21\u6570\u9650\u5236"), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center space-x-2" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "checkbox",
        checked: shareOptions.downloadLimit !== void 0,
        onChange: (e) => setShareOptions((prev) => ({
          ...prev,
          downloadLimit: e.target.checked ? 10 : void 0
        })),
        className: "mr-2"
      }
    ), /* @__PURE__ */ React2.createElement("span", { className: "text-sm text-gray-700" }, "\u9650\u5236\u4E0B\u8F7D\u6B21\u6570"), shareOptions.downloadLimit !== void 0 && /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "number",
        value: shareOptions.downloadLimit,
        onChange: (e) => setShareOptions((prev) => ({
          ...prev,
          downloadLimit: parseInt(e.target.value) || 1
        })),
        min: 1,
        max: 1e3,
        className: "w-20 px-2 py-1 text-sm border border-gray-300 rounded focus:ring-blue-500 focus:border-blue-500"
      }
    ))));
  };
  const renderShareResult = () => {
    if (!shareInfo) return null;
    return /* @__PURE__ */ React2.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React2.createElement("div", { className: "text-center" }, /* @__PURE__ */ React2.createElement("div", { className: "text-4xl mb-4" }, "\u2705"), /* @__PURE__ */ React2.createElement("h3", { className: "text-lg font-medium text-gray-900 mb-2" }, "\u5206\u4EAB\u94FE\u63A5\u5DF2\u521B\u5EFA"), /* @__PURE__ */ React2.createElement("p", { className: "text-sm text-gray-600" }, formatFileList(), " \u5DF2\u6210\u529F\u521B\u5EFA\u5206\u4EAB\u94FE\u63A5")), /* @__PURE__ */ React2.createElement("div", { className: "bg-gray-50 p-4 rounded-lg" }, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u5206\u4EAB\u94FE\u63A5"), /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "text",
        value: shareInfo.shareUrl,
        readOnly: true,
        className: "flex-1 px-3 py-2 text-sm bg-white border border-gray-300 rounded-md"
      }
    ), /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => copyToClipboard(shareInfo.shareUrl),
        className: "px-3 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50"
      },
      "\u590D\u5236\u94FE\u63A5"
    ))), shareInfo.password && /* @__PURE__ */ React2.createElement("div", { className: "bg-yellow-50 p-4 rounded-lg" }, /* @__PURE__ */ React2.createElement("label", { className: "block text-sm font-medium text-gray-700 mb-2" }, "\u8BBF\u95EE\u5BC6\u7801"), /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
      "input",
      {
        type: "text",
        value: shareInfo.password,
        readOnly: true,
        className: "flex-1 px-3 py-2 text-sm bg-white border border-gray-300 rounded-md"
      }
    ), /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => copyToClipboard(shareInfo.password),
        className: "px-3 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50"
      },
      "\u590D\u5236\u5BC6\u7801"
    )), /* @__PURE__ */ React2.createElement("p", { className: "text-xs text-yellow-800 mt-2" }, "\u26A0\uFE0F \u8BF7\u59A5\u5584\u4FDD\u7BA1\u8BBF\u95EE\u5BC6\u7801\uFF0C\u8BBF\u95EE\u8005\u9700\u8981\u6B64\u5BC6\u7801\u624D\u80FD\u67E5\u770B\u6587\u4EF6")), /* @__PURE__ */ React2.createElement("div", { className: "bg-blue-50 p-4 rounded-lg" }, /* @__PURE__ */ React2.createElement("h4", { className: "text-sm font-medium text-blue-900 mb-2" }, "\u5206\u4EAB\u4FE1\u606F"), /* @__PURE__ */ React2.createElement("div", { className: "space-y-1 text-sm text-blue-800" }, /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u6743\u9650\uFF1A"), shareInfo.permission === "view" ? "\u4EC5\u9884\u89C8" : "\u5141\u8BB8\u4E0B\u8F7D"), shareInfo.expiresAt && /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u8FC7\u671F\u65F6\u95F4\uFF1A"), shareInfo.expiresAt.toLocaleString()), /* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("span", { className: "font-medium" }, "\u5206\u4EAB\u4EE3\u7801\uFF1A"), shareInfo.shareCode))), /* @__PURE__ */ React2.createElement("div", { className: "flex space-x-2" }, /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => {
          const shareText = [
            "\u6587\u4EF6\u5206\u4EAB\uFF1A" + formatFileList(),
            "\u94FE\u63A5\uFF1A" + shareInfo.shareUrl,
            shareInfo.password ? "\u5BC6\u7801\uFF1A" + shareInfo.password : "",
            shareInfo.expiresAt ? "\u8FC7\u671F\u65F6\u95F4\uFF1A" + shareInfo.expiresAt.toLocaleString() : "\u6C38\u4E0D\u8FC7\u671F"
          ].filter(Boolean).join("\n");
          copyToClipboard(shareText);
        },
        className: "flex-1 px-4 py-2 text-sm text-blue-600 border border-blue-300 rounded-md hover:bg-blue-50"
      },
      "\u{1F4CB} \u590D\u5236\u5B8C\u6574\u4FE1\u606F"
    ), /* @__PURE__ */ React2.createElement(
      "button",
      {
        onClick: () => {
          console.log("\u5176\u4ED6\u5206\u4EAB\u65B9\u5F0F");
        },
        className: "px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50"
      },
      "\u{1F517} \u5176\u4ED6\u5206\u4EAB\u65B9\u5F0F"
    )));
  };
  return /* @__PURE__ */ React2.createElement("div", { className: "fixed inset-0 z-[50] flex items-center justify-center bg-black bg-opacity-50" }, /* @__PURE__ */ React2.createElement("div", { className: "bg-white rounded-lg max-w-md w-full max-h-[90vh] overflow-hidden" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-between p-4 border-b" }, /* @__PURE__ */ React2.createElement("h2", { className: "text-lg font-medium" }, shareInfo ? "\u5206\u4EAB\u6210\u529F" : "\u521B\u5EFA\u5206\u4EAB\u94FE\u63A5"), /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: onClose,
      className: "p-2 text-gray-400 hover:text-gray-600 rounded-full hover:bg-gray-100"
    },
    "\u2715"
  )), /* @__PURE__ */ React2.createElement("div", { className: "p-6 max-h-[calc(90vh-120px)] overflow-y-auto" }, error && /* @__PURE__ */ React2.createElement("div", { className: "mb-4 p-4 bg-red-50 border border-red-200 rounded-lg" }, /* @__PURE__ */ React2.createElement("p", { className: "text-red-800 text-sm" }, error)), renderShareSettings(), renderShareResult()), !shareInfo && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center justify-end space-x-2 p-4 border-t bg-gray-50" }, /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: onClose,
      className: "px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-md hover:bg-gray-50"
    },
    "\u53D6\u6D88"
  ), /* @__PURE__ */ React2.createElement(
    "button",
    {
      onClick: handleCreateShare,
      disabled: loading || shareOptions.requirePassword && !shareOptions.password,
      className: "px-4 py-2 text-sm text-white bg-blue-600 rounded-md hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
    },
    loading ? /* @__PURE__ */ React2.createElement("span", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2" }), "\u521B\u5EFA\u4E2D...") : "\u521B\u5EFA\u5206\u4EAB\u94FE\u63A5"
  ))));
};
var FileShareModal_default = FileShareModal;

export { ALL_SUPPORTED_MIME_TYPES, API_BASE_PATH, API_ENDPOINTS, AUDIO_EXTENSIONS, AUDIO_MIME_TYPES, DEFAULT_CHUNK_SIZE, DEFAULT_MAX_AUDIO_SIZE, DEFAULT_MAX_DOCUMENT_SIZE, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_IMAGE_SIZE, DEFAULT_MAX_VIDEO_SIZE, DEFAULT_PAGE_SIZE, DEFAULT_REQUEST_TIMEOUT, DEFAULT_UPLOAD_TIMEOUT, DOCUMENT_EXTENSIONS, DOCUMENT_MIME_TYPES, ERROR_CODES, FileShareModal_default as FileShareModal, FileUploader, FolderManager_default as FolderManager, IMAGE_EXTENSIONS, IMAGE_MIME_TYPES, UNIVERSAL_FILE_NAME, UNIVERSAL_FILE_VERSION, UniversalFileClient, UniversalFileManager, VIDEO_EXTENSIONS, VIDEO_MIME_TYPES, buildQueryString, calculateProgress, calculateRemainingTime, calculateSpeed, createFileClient, createFileError, formatErrorMessage, formatFileSize, generateStoragePath, generateUniqueFileName, getFileCategory, getFileExtension, getMimeTypeFromFileName, isAudioFile, isDocumentFile, isImageFile, isMimeTypeSupported, isVideoFile, parseFileSize, parseQueryString, parseStoragePath, readFileAsArrayBuffer, readFileAsBase64, readFileAsText, sanitizeFileName, universalFileClient, validateFile, validateFileName, validateFileSize, validateFileType };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map