import React, { useState, useCallback, useEffect } from 'react';
import { clsx } from 'clsx';
import { Settings, X, Eye, EyeOff, MoveUp, MoveDown, Trash2, Group, Save, Loader2, Download, ChevronDown, Type, Database, FileText, FileSpreadsheet } from 'lucide-react';

// src/universalExport/constants.ts
var UNIVERSAL_EXPORT_VERSION = "1.0.0";
var UNIVERSAL_EXPORT_NAME = "@lyricnote/universal-export";
var DEFAULT_EXPORT_FORMAT = "csv";
var DEFAULT_CSV_DELIMITER = ",";
var DEFAULT_ENCODING = "utf-8";
var DEFAULT_ADD_BOM = true;
var DEFAULT_MAX_FILE_SIZE = 100 * 1024 * 1024;
var DEFAULT_MAX_ROWS = 1e5;
var DEFAULT_MAX_CONCURRENT_EXPORTS = 5;
var DEFAULT_EXPORT_TIMEOUT = 3e5;
var DEFAULT_CONFIG_CACHE_TTL = 3600;
var DEFAULT_RESULT_CACHE_TTL = 1800;
var EXPORT_FORMAT_EXTENSIONS = {
  csv: "csv",
  excel: "xlsx",
  json: "json"
};
var EXPORT_FORMAT_MIME_TYPES = {
  csv: "text/csv; charset=utf-8",
  excel: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  json: "application/json; charset=utf-8"
};
var API_BASE_PATH = "/api/universal-export";
var API_ENDPOINTS = {
  /** 获取配置列表 */
  GET_CONFIGS: API_BASE_PATH + "/configs",
  /** 创建配置 */
  CREATE_CONFIG: API_BASE_PATH + "/configs",
  /** 更新配置 */
  UPDATE_CONFIG: (configId) => API_BASE_PATH + "/configs/" + configId,
  /** 删除配置 */
  DELETE_CONFIG: (configId) => API_BASE_PATH + "/configs/" + configId,
  /** 触发导出 */
  EXPORT_DATA: API_BASE_PATH + "/export",
  /** 查询导出进度 */
  GET_PROGRESS: (exportId) => API_BASE_PATH + "/export/" + exportId + "/progress",
  /** 下载导出文件 */
  DOWNLOAD_FILE: (exportId) => API_BASE_PATH + "/export/" + exportId + "/download"
};
var ERROR_CODES = {
  /** 导出配置错误 */
  EXPORT_CONFIG_ERROR: "EXPORT_CONFIG_ERROR",
  /** 导出数据错误 */
  EXPORT_DATA_ERROR: "EXPORT_DATA_ERROR",
  /** 导出文件错误 */
  EXPORT_FILE_ERROR: "EXPORT_FILE_ERROR",
  /** 网络错误 */
  NETWORK_ERROR: "NETWORK_ERROR",
  /** 超时错误 */
  TIMEOUT_ERROR: "TIMEOUT_ERROR",
  /** 未授权 */
  UNAUTHORIZED: "UNAUTHORIZED",
  /** 服务器错误 */
  SERVER_ERROR: "SERVER_ERROR"
};

// src/universalExport/utils.ts
function generateExportFileName(template, format) {
  const now = /* @__PURE__ */ new Date();
  const dateStr = now.toISOString().split("T")[0] || "";
  const timeStr = (now.toTimeString().split(" ")[0] || "").replace(/:/g, "-");
  const extension = EXPORT_FORMAT_EXTENSIONS[format];
  return template.replace("{date}", dateStr).replace("{time}", timeStr).replace("{timestamp}", now.getTime().toString()) + "." + extension;
}
function validateFileName(fileName) {
  const invalidChars = /[<>:"|?*\/\\]/;
  if (invalidChars.test(fileName)) {
    return false;
  }
  if (fileName.length === 0 || fileName.length > 255) {
    return false;
  }
  return true;
}
function sanitizeFileName(fileName) {
  return fileName.replace(/[<>:"|?*\/\\]/g, "_").substring(0, 255);
}
function escapeCSVField(value, delimiter = ",") {
  const valueStr = String(value || "");
  if (valueStr.includes(delimiter) || valueStr.includes('"') || valueStr.includes("\n")) {
    return '"' + valueStr.replace(/"/g, '""') + '"';
  }
  return valueStr;
}
function parseCSVField(field) {
  if (field.startsWith('"') && field.endsWith('"')) {
    return field.slice(1, -1).replace(/""/g, '"');
  }
  return field;
}
var DEFAULT_FORMATTERS = {
  // 日期格式化
  date: (value) => {
    if (!value) return "";
    const date = new Date(value);
    if (isNaN(date.getTime())) return String(value);
    return date.toISOString().split("T")[0] || "";
  },
  // 时间格式化
  datetime: (value) => {
    if (!value) return "";
    const date = new Date(value);
    if (isNaN(date.getTime())) return String(value);
    return date.toLocaleString("zh-CN");
  },
  // 数字格式化
  number: (value) => {
    if (value === null || value === void 0) return "";
    return String(value);
  },
  // 货币格式化
  currency: (value) => {
    if (value === null || value === void 0) return "";
    return "\xA5" + Number(value).toFixed(2);
  },
  // 百分比格式化
  percentage: (value) => {
    if (value === null || value === void 0) return "";
    return (Number(value) * 100).toFixed(2) + "%";
  },
  // 布尔值格式化
  boolean: (value) => {
    if (value === null || value === void 0) return "";
    return value ? "\u662F" : "\u5426";
  },
  // 数组格式化
  array: (value) => {
    if (!Array.isArray(value)) return "";
    return value.join(", ");
  },
  // 对象格式化
  object: (value) => {
    if (!value || typeof value !== "object") return "";
    return JSON.stringify(value);
  }
};
function applyFormatter(value, formatter, type) {
  if (formatter) {
    return formatter(value);
  }
  if (type && DEFAULT_FORMATTERS[type]) {
    return DEFAULT_FORMATTERS[type](value);
  }
  return String(value || "");
}
function validateExportConfig(config) {
  const errors = [];
  if (!config.name || config.name.trim() === "") {
    errors.push("\u914D\u7F6E\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
  }
  if (!config.fields || !Array.isArray(config.fields) || config.fields.length === 0) {
    errors.push("\u81F3\u5C11\u9700\u8981\u5B9A\u4E49\u4E00\u4E2A\u5B57\u6BB5");
  }
  if (config.fields) {
    const enabledFields = config.fields.filter((f) => f.enabled);
    if (enabledFields.length === 0) {
      errors.push("\u81F3\u5C11\u9700\u8981\u542F\u7528\u4E00\u4E2A\u5B57\u6BB5");
    }
    const keys = config.fields.map((f) => f.key);
    const uniqueKeys = new Set(keys);
    if (keys.length !== uniqueKeys.size) {
      errors.push("\u5B57\u6BB5\u952E\u540D\u5FC5\u987B\u552F\u4E00");
    }
  }
  return {
    valid: errors.length === 0,
    errors
  };
}
function validateExportRequest(request) {
  const errors = [];
  if (!request.configId) {
    errors.push("\u5BFC\u51FA\u914D\u7F6EID\u4E0D\u80FD\u4E3A\u7A7A");
  }
  if (!request.dataSource) {
    errors.push("\u6570\u636E\u6E90\u4E0D\u80FD\u4E3A\u7A7A");
  }
  return {
    valid: errors.length === 0,
    errors
  };
}
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 formatDuration(milliseconds) {
  if (milliseconds < 1e3) {
    return milliseconds + "ms";
  }
  const seconds = Math.floor(milliseconds / 1e3);
  if (seconds < 60) {
    return seconds + "\u79D2";
  }
  const minutes = Math.floor(seconds / 60);
  const remainingSeconds = seconds % 60;
  if (minutes < 60) {
    return remainingSeconds > 0 ? minutes + "\u5206" + remainingSeconds + "\u79D2" : minutes + "\u5206\u949F";
  }
  const hours = Math.floor(minutes / 60);
  const remainingMinutes = minutes % 60;
  return remainingMinutes > 0 ? hours + "\u5C0F\u65F6" + remainingMinutes + "\u5206\u949F" : hours + "\u5C0F\u65F6";
}
function estimateEndTime(startTime, processedRows, totalRows) {
  if (processedRows === 0 || totalRows === 0) {
    return void 0;
  }
  const elapsed = Date.now() - startTime.getTime();
  const avgTimePerRow = elapsed / processedRows;
  const remainingRows = totalRows - processedRows;
  const remainingTime = avgTimePerRow * remainingRows;
  return new Date(Date.now() + remainingTime);
}
function getNestedValue(obj, path) {
  return path.split(".").reduce((current, key) => {
    return current && current[key] !== void 0 ? current[key] : null;
  }, obj);
}
function setNestedValue(obj, path, value) {
  const keys = path.split(".");
  const lastKey = keys.pop();
  if (!lastKey) return;
  const target = keys.reduce((current, key) => {
    if (!current[key] || typeof current[key] !== "object") {
      current[key] = {};
    }
    return current[key];
  }, obj);
  target[lastKey] = value;
}
function createExportError(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;
  }
  return "\u672A\u77E5\u9519\u8BEF";
}

// src/universalExport/client.ts
var UniversalExportClient = class {
  constructor(config = {}) {
    this.config = {
      baseUrl: config.baseUrl || "",
      timeout: config.timeout || 3e4,
      headers: config.headers || {}
    };
  }
  // ============= 配置管理API =============
  /**
   * 获取模块的导出配置列表
   */
  async getConfigsByModule(moduleId, businessId) {
    const params = new URLSearchParams({ moduleId });
    if (businessId) {
      params.append("businessId", businessId);
    }
    const url = this.config.baseUrl + API_ENDPOINTS.GET_CONFIGS + "?" + params;
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "GET",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        throw new Error("\u83B7\u53D6\u914D\u7F6E\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return this.transformConfigsFromAPI(data.configs || []);
    } catch (error) {
      throw createExportError(
        ERROR_CODES.NETWORK_ERROR,
        "\u83B7\u53D6\u5BFC\u51FA\u914D\u7F6E\u5931\u8D25: " + formatErrorMessage(error),
        { moduleId, businessId, originalError: error }
      );
    }
  }
  /**
   * 创建导出配置
   */
  async createConfig(config) {
    const url = this.config.baseUrl + API_ENDPOINTS.CREATE_CONFIG;
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "POST",
        headers: {
          ...this.getHeaders(),
          "Content-Type": "application/json"
        },
        body: JSON.stringify(config)
      });
      if (!response.ok) {
        throw new Error("\u521B\u5EFA\u914D\u7F6E\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return this.transformConfigFromAPI(data.config);
    } catch (error) {
      throw createExportError(
        ERROR_CODES.NETWORK_ERROR,
        "\u521B\u5EFA\u5BFC\u51FA\u914D\u7F6E\u5931\u8D25: " + formatErrorMessage(error),
        { config, originalError: error }
      );
    }
  }
  /**
   * 更新导出配置
   */
  async updateConfig(configId, updates) {
    const url = this.config.baseUrl + API_ENDPOINTS.UPDATE_CONFIG(configId);
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "PUT",
        headers: {
          ...this.getHeaders(),
          "Content-Type": "application/json"
        },
        body: JSON.stringify(updates)
      });
      if (!response.ok) {
        throw new Error("\u66F4\u65B0\u914D\u7F6E\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return this.transformConfigFromAPI(data.config);
    } catch (error) {
      throw createExportError(
        ERROR_CODES.NETWORK_ERROR,
        "\u66F4\u65B0\u5BFC\u51FA\u914D\u7F6E\u5931\u8D25: " + formatErrorMessage(error),
        { configId, updates, originalError: error }
      );
    }
  }
  /**
   * 删除导出配置
   */
  async deleteConfig(configId) {
    const url = this.config.baseUrl + API_ENDPOINTS.DELETE_CONFIG(configId);
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "DELETE",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        throw new Error("\u5220\u9664\u914D\u7F6E\u5931\u8D25: " + response.statusText);
      }
    } catch (error) {
      throw createExportError(
        ERROR_CODES.NETWORK_ERROR,
        "\u5220\u9664\u5BFC\u51FA\u914D\u7F6E\u5931\u8D25: " + formatErrorMessage(error),
        { configId, originalError: error }
      );
    }
  }
  // ============= 导出执行API =============
  /**
   * 触发数据导出
   */
  async exportData(request) {
    const url = this.config.baseUrl + API_ENDPOINTS.EXPORT_DATA;
    try {
      const isDataArray = Array.isArray(request.dataSource);
      const requestBody = {
        configId: request.configId,
        queryParams: request.queryParams,
        fieldMapping: request.fieldMapping,
        filters: request.filters,
        sortBy: request.sortBy,
        pagination: request.pagination,
        customFileName: request.customFileName
      };
      if (isDataArray) {
        requestBody.data = request.dataSource;
      } else {
        requestBody.dataSource = request.dataSource;
      }
      const response = await this.fetchWithTimeout(url, {
        method: "POST",
        headers: {
          ...this.getHeaders(),
          "Content-Type": "application/json"
        },
        body: JSON.stringify(requestBody)
      });
      if (!response.ok) {
        const errorText = await response.text();
        let errorData;
        try {
          errorData = JSON.parse(errorText);
        } catch {
          errorData = { message: errorText };
        }
        throw new Error(errorData.message || "\u5BFC\u51FA\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return this.transformExportResultFromAPI(data.result);
    } catch (error) {
      throw createExportError(
        ERROR_CODES.EXPORT_DATA_ERROR,
        "\u6570\u636E\u5BFC\u51FA\u5931\u8D25: " + formatErrorMessage(error),
        { request, originalError: error }
      );
    }
  }
  /**
   * 查询导出进度
   */
  async getExportProgress(exportId) {
    const url = this.config.baseUrl + API_ENDPOINTS.GET_PROGRESS(exportId);
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "GET",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        throw new Error("\u83B7\u53D6\u5BFC\u51FA\u8FDB\u5EA6\u5931\u8D25: " + response.statusText);
      }
      const data = await response.json();
      return this.transformProgressFromAPI(data.progress);
    } catch (error) {
      throw createExportError(
        ERROR_CODES.NETWORK_ERROR,
        "\u83B7\u53D6\u5BFC\u51FA\u8FDB\u5EA6\u5931\u8D25: " + formatErrorMessage(error),
        { exportId, originalError: error }
      );
    }
  }
  /**
   * 下载导出文件
   */
  async downloadExportFile(exportId) {
    const url = this.config.baseUrl + API_ENDPOINTS.DOWNLOAD_FILE(exportId);
    try {
      const response = await this.fetchWithTimeout(url, {
        method: "GET",
        headers: this.getHeaders()
      });
      if (!response.ok) {
        throw new Error("\u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25: " + response.statusText);
      }
      return await response.blob();
    } catch (error) {
      throw createExportError(
        ERROR_CODES.NETWORK_ERROR,
        "\u4E0B\u8F7D\u5BFC\u51FA\u6587\u4EF6\u5931\u8D25: " + formatErrorMessage(error),
        { exportId, 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
      });
      return response;
    } catch (error) {
      if (error instanceof Error && error.name === "AbortError") {
        throw createExportError(ERROR_CODES.TIMEOUT_ERROR, "\u8BF7\u6C42\u8D85\u65F6", {
          url,
          timeout: this.config.timeout
        });
      }
      throw error;
    } finally {
      clearTimeout(timeoutId);
    }
  }
  /**
   * 转换API返回的配置数据
   */
  transformConfigFromAPI(apiConfig) {
    return {
      id: apiConfig.id,
      name: apiConfig.name,
      description: apiConfig.description || void 0,
      format: apiConfig.format,
      fields: apiConfig.fields,
      grouping: apiConfig.grouping,
      fileNameTemplate: apiConfig.fileNameTemplate,
      includeHeader: apiConfig.includeHeader,
      delimiter: apiConfig.delimiter,
      encoding: apiConfig.encoding,
      addBOM: apiConfig.addBOM,
      maxRows: apiConfig.maxRows || void 0,
      createdAt: new Date(apiConfig.createdAt),
      updatedAt: new Date(apiConfig.updatedAt),
      moduleId: apiConfig.moduleId,
      businessId: apiConfig.businessId || void 0,
      createdBy: apiConfig.createdBy || void 0
    };
  }
  /**
   * 转换API返回的配置列表
   */
  transformConfigsFromAPI(apiConfigs) {
    return apiConfigs.map((config) => this.transformConfigFromAPI(config));
  }
  /**
   * 转换API返回的导出结果
   */
  transformExportResultFromAPI(apiResult) {
    return {
      exportId: apiResult.exportId,
      fileName: apiResult.fileName,
      fileSize: apiResult.fileSize,
      fileUrl: apiResult.fileUrl,
      exportedRows: apiResult.exportedRows,
      startTime: new Date(apiResult.startTime),
      endTime: new Date(apiResult.endTime),
      duration: apiResult.duration,
      statistics: apiResult.statistics
    };
  }
  /**
   * 转换API返回的进度数据
   */
  transformProgressFromAPI(apiProgress) {
    return {
      exportId: apiProgress.exportId,
      status: apiProgress.status,
      progress: apiProgress.progress,
      processedRows: apiProgress.processedRows,
      totalRows: apiProgress.totalRows,
      startTime: new Date(apiProgress.startTime),
      estimatedEndTime: apiProgress.estimatedEndTime ? new Date(apiProgress.estimatedEndTime) : void 0,
      currentData: apiProgress.currentData,
      error: apiProgress.error
    };
  }
};
var universalExportClient = new UniversalExportClient();
function createExportClient(config) {
  return new UniversalExportClient(config);
}
var FORMAT_ICONS = {
  csv: /* @__PURE__ */ React.createElement(FileText, { className: "w-4 h-4" }),
  excel: /* @__PURE__ */ React.createElement(FileSpreadsheet, { className: "w-4 h-4" }),
  json: /* @__PURE__ */ React.createElement(Database, { className: "w-4 h-4" })
};
var FORMAT_DESCRIPTIONS = {
  csv: "\u9017\u53F7\u5206\u9694\u503C\u6587\u4EF6\uFF0C\u517C\u5BB9\u6027\u6700\u597D",
  excel: "Excel\u8868\u683C\u6587\u4EF6\uFF0C\u652F\u6301\u683C\u5F0F\u5316\u548C\u5355\u5143\u683C\u5408\u5E76",
  json: "JSON\u6570\u636E\u6587\u4EF6\uFF0C\u9002\u5408\u5F00\u53D1\u8005\u4F7F\u7528"
};
var ExportConfigEditor = ({
  initialConfig,
  moduleId,
  businessId,
  availableFields,
  onSave,
  onCancel,
  visible = false,
  className = "",
  onConfigChange
}) => {
  const [config, setConfig] = useState(() => {
    if (initialConfig) {
      return { ...initialConfig };
    }
    return {
      id: "",
      name: "\u65B0\u5EFA\u5BFC\u51FA\u914D\u7F6E",
      description: "",
      format: "csv",
      fields: availableFields.map((field, index) => ({
        ...field,
        enabled: true,
        sortOrder: index
      })),
      grouping: {
        enabled: false,
        fields: [],
        preserveOrder: true,
        nullValueHandling: "separate",
        nullGroupName: "\u672A\u5206\u7EC4"
      },
      fileNameTemplate: "\u5BFC\u51FA\u6570\u636E_{date}",
      includeHeader: true,
      delimiter: ",",
      encoding: "utf-8",
      addBOM: true,
      maxRows: void 0,
      createdAt: /* @__PURE__ */ new Date(),
      updatedAt: /* @__PURE__ */ new Date(),
      moduleId,
      businessId
    };
  });
  const [activeTab, setActiveTab] = useState("basic");
  const [savedConfigs, setSavedConfigs] = useState([]);
  const [loadingConfigs, setLoadingConfigs] = useState(false);
  const [deletingConfigId, setDeletingConfigId] = useState(null);
  const loadSavedConfigs = useCallback(async () => {
    if (!visible || activeTab !== "manage") return;
    setLoadingConfigs(true);
    try {
      const params = new URLSearchParams({ moduleId });
      if (businessId) {
        params.set("businessId", businessId);
      }
      const response = await fetch("/api/universal-export/configs?" + params.toString());
      if (response.ok) {
        const data = await response.json();
        setSavedConfigs(data.configs || []);
      }
    } catch (error) {
      console.error("\u52A0\u8F7D\u914D\u7F6E\u5F02\u5E38:", error);
    } finally {
      setLoadingConfigs(false);
    }
  }, [visible, activeTab, moduleId, businessId]);
  const deleteConfig = useCallback(async (configId) => {
    setDeletingConfigId(configId);
    try {
      const response = await fetch("/api/universal-export/configs/" + configId, {
        method: "DELETE"
      });
      if (response.ok) {
        setSavedConfigs((prev) => prev.filter((cfg) => cfg.id !== configId));
        onConfigChange?.();
      }
    } catch (error) {
      console.error("\u5220\u9664\u914D\u7F6E\u5931\u8D25:", error);
    } finally {
      setDeletingConfigId(null);
    }
  }, [onConfigChange]);
  const loadConfigToEditor = useCallback((config2) => {
    setConfig(config2);
    setActiveTab("basic");
  }, []);
  useEffect(() => {
    if (activeTab === "manage") {
      loadSavedConfigs();
    }
  }, [activeTab, loadSavedConfigs]);
  useEffect(() => {
    if (!visible) return;
    const scrollY = window.scrollY;
    document.body.style.position = "fixed";
    document.body.style.top = "-" + scrollY + "px";
    document.body.style.left = "0";
    document.body.style.right = "0";
    document.body.style.overflow = "hidden";
    const handleKeyDown = (e) => {
      if (e.key === "Escape") {
        onCancel?.();
      }
    };
    document.addEventListener("keydown", handleKeyDown);
    return () => {
      document.body.style.position = "";
      document.body.style.top = "";
      document.body.style.left = "";
      document.body.style.right = "";
      document.body.style.overflow = "";
      window.scrollTo(0, scrollY);
      document.removeEventListener("keydown", handleKeyDown);
    };
  }, [visible, onCancel]);
  const toggleFieldEnabled = useCallback((fieldKey) => {
    setConfig((prev) => ({
      ...prev,
      fields: prev.fields.map(
        (field) => field.key === fieldKey ? { ...field, enabled: !field.enabled } : field
      )
    }));
  }, []);
  useCallback((fieldKey, updates) => {
    setConfig((prev) => ({
      ...prev,
      fields: prev.fields.map(
        (field) => field.key === fieldKey ? { ...field, ...updates } : field
      )
    }));
  }, []);
  const moveField = useCallback((fieldKey, direction) => {
    setConfig((prev) => {
      const fields = [...prev.fields];
      const index = fields.findIndex((f) => f.key === fieldKey);
      if (direction === "up" && index > 0) {
        const temp = fields[index - 1];
        fields[index - 1] = fields[index];
        fields[index] = temp;
      } else if (direction === "down" && index < fields.length - 1) {
        const temp = fields[index + 1];
        fields[index + 1] = fields[index];
        fields[index] = temp;
      }
      return {
        ...prev,
        fields: fields.map((field, idx) => ({ ...field, sortOrder: idx }))
      };
    });
  }, []);
  const removeField = useCallback((fieldKey) => {
    setConfig((prev) => ({
      ...prev,
      fields: prev.fields.filter((f) => f.key !== fieldKey)
    }));
  }, []);
  const toggleGrouping = useCallback((enabled) => {
    setConfig((prev) => ({
      ...prev,
      grouping: {
        ...prev.grouping,
        enabled
      }
    }));
  }, []);
  const addGroupingField = useCallback((fieldKey) => {
    const field = config.fields.find((f) => f.key === fieldKey);
    if (!field) return;
    const groupField = {
      key: field.key,
      label: field.label,
      mode: "merge",
      valueProcessing: "first",
      showGroupHeader: false,
      mergeCells: true
    };
    setConfig((prev) => ({
      ...prev,
      grouping: {
        ...prev.grouping,
        fields: [...prev.grouping.fields, groupField]
      }
    }));
  }, [config.fields]);
  const removeGroupingField = useCallback((fieldKey) => {
    setConfig((prev) => ({
      ...prev,
      grouping: {
        ...prev.grouping,
        fields: prev.grouping.fields.filter((f) => f.key !== fieldKey)
      }
    }));
  }, []);
  const updateGroupingField = useCallback((fieldKey, updates) => {
    setConfig((prev) => ({
      ...prev,
      grouping: {
        ...prev.grouping,
        fields: prev.grouping.fields.map(
          (field) => field.key === fieldKey ? { ...field, ...updates } : field
        )
      }
    }));
  }, []);
  useCallback((fieldKey, direction) => {
    setConfig((prev) => {
      const fields = [...prev.grouping.fields];
      const index = fields.findIndex((f) => f.key === fieldKey);
      if (direction === "up" && index > 0) {
        const temp = fields[index - 1];
        fields[index - 1] = fields[index];
        fields[index] = temp;
      } else if (direction === "down" && index < fields.length - 1) {
        const temp = fields[index + 1];
        fields[index + 1] = fields[index];
        fields[index] = temp;
      }
      return {
        ...prev,
        grouping: {
          ...prev.grouping,
          fields
        }
      };
    });
  }, []);
  useCallback((updates) => {
    setConfig((prev) => ({
      ...prev,
      grouping: {
        ...prev.grouping,
        ...updates
      }
    }));
  }, []);
  const handleSave = useCallback(() => {
    if (!config.name.trim()) {
      alert("\u8BF7\u8F93\u5165\u914D\u7F6E\u540D\u79F0");
      return;
    }
    const enabledFields = config.fields.filter((f) => f.enabled);
    if (enabledFields.length === 0) {
      alert("\u81F3\u5C11\u9700\u8981\u542F\u7528\u4E00\u4E2A\u5B57\u6BB5");
      return;
    }
    const updatedConfig = {
      ...config,
      updatedAt: /* @__PURE__ */ new Date()
    };
    onSave?.(updatedConfig);
    onConfigChange?.();
  }, [config, onSave, onConfigChange]);
  if (!visible) {
    return null;
  }
  const tabs = [
    { id: "basic", label: "\u57FA\u672C\u914D\u7F6E", icon: /* @__PURE__ */ React.createElement(Settings, { className: "w-4 h-4" }), description: "\u914D\u7F6E\u540D\u79F0\u3001\u683C\u5F0F\u548C\u57FA\u672C\u9009\u9879" },
    { id: "fields", label: "\u5B57\u6BB5\u8BBE\u7F6E", icon: /* @__PURE__ */ React.createElement(Type, { className: "w-4 h-4" }), description: "\u9009\u62E9\u548C\u914D\u7F6E\u5BFC\u51FA\u5B57\u6BB5" },
    { id: "grouping", label: "\u5206\u7EC4\u8BBE\u7F6E", icon: /* @__PURE__ */ React.createElement(Group, { className: "w-4 h-4" }), description: "\u914D\u7F6E\u6570\u636E\u5206\u7EC4\u548C\u5408\u5E76\u9009\u9879" },
    { id: "manage", label: "\u914D\u7F6E\u7BA1\u7406", icon: /* @__PURE__ */ React.createElement(Database, { className: "w-4 h-4" }), description: "\u7BA1\u7406\u5DF2\u4FDD\u5B58\u7684\u5BFC\u51FA\u914D\u7F6E" }
  ];
  return /* @__PURE__ */ React.createElement(
    "div",
    {
      className: clsx("fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[50] p-4", className),
      onClick: onCancel
    },
    /* @__PURE__ */ React.createElement(
      "div",
      {
        className: "bg-white rounded-lg shadow-xl w-full max-w-5xl max-h-[90vh] flex flex-col",
        onClick: (e) => e.stopPropagation()
      },
      /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between p-4 border-b flex-shrink-0" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ React.createElement(Settings, { className: "w-6 h-6 text-blue-600" }), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold text-gray-900" }, "\u5BFC\u51FA\u914D\u7F6E\u7F16\u8F91\u5668"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-600" }, "\u914D\u7F6E\u5BFC\u51FA\u5B57\u6BB5\u548C\u683C\u5F0F\u9009\u9879"))), /* @__PURE__ */ React.createElement("button", { onClick: onCancel, className: "p-2 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg" }, /* @__PURE__ */ React.createElement(X, { className: "w-5 h-5" }))),
      /* @__PURE__ */ React.createElement("div", { className: "border-b bg-gray-50 flex-shrink-0" }, /* @__PURE__ */ React.createElement("nav", { className: "flex space-x-1 p-2" }, tabs.map((tab) => /* @__PURE__ */ React.createElement(
        "button",
        {
          key: tab.id,
          onClick: () => setActiveTab(tab.id),
          className: clsx("flex items-center gap-2 px-4 py-3 text-sm font-medium rounded-lg transition-colors", activeTab === tab.id ? "bg-white text-blue-600 shadow-sm border border-gray-200" : "text-gray-600 hover:text-gray-900")
        },
        tab.icon,
        /* @__PURE__ */ React.createElement("span", null, tab.label)
      )))),
      /* @__PURE__ */ React.createElement("div", { className: "flex-1 overflow-hidden flex flex-col" }, /* @__PURE__ */ React.createElement("div", { className: "bg-blue-50 border-b border-blue-100 p-4 flex-shrink-0" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 text-blue-800 text-sm font-medium" }, tabs.find((t) => t.id === activeTab)?.icon, tabs.find((t) => t.id === activeTab)?.description)), /* @__PURE__ */ React.createElement("div", { className: "flex-1 overflow-y-auto p-4 sm:p-6" }, activeTab === "basic" && /* @__PURE__ */ React.createElement("div", { className: "max-w-2xl mx-auto space-y-6" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("label", { className: "block text-sm font-medium text-gray-700" }, "\u914D\u7F6E\u540D\u79F0 *"), /* @__PURE__ */ React.createElement(
        "input",
        {
          type: "text",
          value: config.name,
          onChange: (e) => setConfig((prev) => ({ ...prev, name: e.target.value })),
          className: "w-full px-3 py-2 border border-gray-300 rounded-lg"
        }
      ), /* @__PURE__ */ React.createElement("label", { className: "block text-sm font-medium text-gray-700" }, "\u63CF\u8FF0"), /* @__PURE__ */ React.createElement(
        "textarea",
        {
          value: config.description,
          onChange: (e) => setConfig((prev) => ({ ...prev, description: e.target.value })),
          className: "w-full px-3 py-2 border border-gray-300 rounded-lg",
          rows: 3
        }
      ), /* @__PURE__ */ React.createElement("label", { className: "block text-sm font-medium text-gray-700" }, "\u5BFC\u51FA\u683C\u5F0F"), /* @__PURE__ */ React.createElement("div", { className: "space-y-3" }, ["csv", "excel", "json"].map((format) => /* @__PURE__ */ React.createElement("label", { key: format, className: "flex items-start gap-3 p-3 border rounded-lg cursor-pointer hover:border-blue-300" }, /* @__PURE__ */ React.createElement(
        "input",
        {
          type: "radio",
          checked: config.format === format,
          onChange: () => setConfig((prev) => ({ ...prev, format })),
          className: "mt-1"
        }
      ), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 font-medium" }, FORMAT_ICONS[format], " ", format.toUpperCase()), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-gray-600" }, FORMAT_DESCRIPTIONS[format]))))))), activeTab === "fields" && /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, config.fields.map((field, index) => /* @__PURE__ */ React.createElement("div", { key: field.key, className: "flex items-center gap-3 p-3 border rounded-lg bg-white" }, /* @__PURE__ */ React.createElement("button", { onClick: () => toggleFieldEnabled(field.key), className: field.enabled ? "text-blue-600" : "text-gray-400" }, field.enabled ? /* @__PURE__ */ React.createElement(Eye, { className: "w-4 h-4" }) : /* @__PURE__ */ React.createElement(EyeOff, { className: "w-4 h-4" })), /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "font-medium" }, field.label), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-gray-500" }, field.key)), /* @__PURE__ */ React.createElement("div", { className: "flex gap-1" }, /* @__PURE__ */ React.createElement("button", { onClick: () => moveField(field.key, "up"), disabled: index === 0, className: "disabled:opacity-30" }, /* @__PURE__ */ React.createElement(MoveUp, { className: "w-4 h-4" })), /* @__PURE__ */ React.createElement("button", { onClick: () => moveField(field.key, "down"), disabled: index === config.fields.length - 1, className: "disabled:opacity-30" }, /* @__PURE__ */ React.createElement(MoveDown, { className: "w-4 h-4" })), /* @__PURE__ */ React.createElement("button", { onClick: () => removeField(field.key), className: "text-red-600" }, /* @__PURE__ */ React.createElement(Trash2, { className: "w-4 h-4" })))))), activeTab === "grouping" && /* @__PURE__ */ React.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-medium flex items-center gap-2" }, /* @__PURE__ */ React.createElement(Group, { className: "w-5 h-5 text-blue-600" }), " \u5206\u7EC4\u914D\u7F6E"), /* @__PURE__ */ React.createElement("label", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("input", { type: "checkbox", checked: config.grouping?.enabled, onChange: (e) => toggleGrouping(e.target.checked) }), "\u542F\u7528\u5206\u7EC4")), config.grouping?.enabled && /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, config.grouping.fields.map((gf, index) => /* @__PURE__ */ React.createElement("div", { key: gf.key, className: "p-4 border rounded-lg bg-blue-50 border-blue-200" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-center mb-4" }, /* @__PURE__ */ React.createElement("span", { className: "font-medium text-blue-900" }, gf.label), /* @__PURE__ */ React.createElement("button", { onClick: () => removeGroupingField(gf.key), className: "text-red-600" }, /* @__PURE__ */ React.createElement(Trash2, { className: "w-4 h-4" }))), /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-4" }, /* @__PURE__ */ React.createElement("select", { value: gf.mode, onChange: (e) => updateGroupingField(gf.key, { mode: e.target.value }), className: "border rounded p-2" }, /* @__PURE__ */ React.createElement("option", { value: "merge" }, "\u5408\u5E76\u6A21\u5F0F"), /* @__PURE__ */ React.createElement("option", { value: "separate" }, "\u5206\u79BB\u6A21\u5F0F"), /* @__PURE__ */ React.createElement("option", { value: "nested" }, "\u5D4C\u5957\u6A21\u5F0F")), /* @__PURE__ */ React.createElement("select", { value: gf.valueProcessing, onChange: (e) => updateGroupingField(gf.key, { valueProcessing: e.target.value }), className: "border rounded p-2" }, /* @__PURE__ */ React.createElement("option", { value: "first" }, "\u9996\u503C"), /* @__PURE__ */ React.createElement("option", { value: "sum" }, "\u6C42\u548C"), /* @__PURE__ */ React.createElement("option", { value: "count" }, "\u8BA1\u6570"))))), /* @__PURE__ */ React.createElement("select", { onChange: (e) => e.target.value && addGroupingField(e.target.value), className: "w-full border rounded p-2" }, /* @__PURE__ */ React.createElement("option", { value: "" }, "\u6DFB\u52A0\u5206\u7EC4\u5B57\u6BB5..."), config.fields.filter((f) => f.enabled && !config.grouping?.fields.some((gf) => gf.key === f.key)).map((f) => /* @__PURE__ */ React.createElement("option", { key: f.key, value: f.key }, f.label))))), activeTab === "manage" && /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, loadingConfigs ? /* @__PURE__ */ React.createElement("div", { className: "text-center py-10" }, "\u52A0\u8F7D\u4E2D...") : savedConfigs.map((sc) => /* @__PURE__ */ React.createElement("div", { key: sc.id, className: "flex justify-between items-center p-4 border rounded-lg" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "font-medium" }, sc.name), /* @__PURE__ */ React.createElement("div", { className: "text-sm text-gray-500" }, sc.format)), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement("button", { onClick: () => loadConfigToEditor(sc), className: "text-blue-600 px-3 py-1 border rounded" }, "\u7F16\u8F91"), /* @__PURE__ */ React.createElement("button", { onClick: () => deleteConfig(sc.id), className: "text-red-600 px-3 py-1 border rounded" }, "\u5220\u9664"))))))),
      /* @__PURE__ */ React.createElement("div", { className: "flex justify-end gap-3 p-4 border-t bg-gray-50" }, /* @__PURE__ */ React.createElement("button", { onClick: onCancel, className: "px-4 py-2 border rounded" }, "\u53D6\u6D88"), activeTab !== "manage" && /* @__PURE__ */ React.createElement("button", { onClick: handleSave, className: "px-4 py-2 bg-blue-600 text-white rounded flex items-center gap-2" }, /* @__PURE__ */ React.createElement(Save, { className: "w-4 h-4" }), " \u4FDD\u5B58\u914D\u7F6E"))
    )
  );
};

// src/universalExport/components/UniversalExportButton.tsx
var BUTTON_STYLES = {
  primary: {
    sm: "px-3 py-1.5 text-sm bg-blue-600 text-white hover:bg-blue-700",
    md: "px-4 py-2 text-sm bg-blue-600 text-white hover:bg-blue-700",
    lg: "px-6 py-3 text-base bg-blue-600 text-white hover:bg-blue-700"
  },
  secondary: {
    sm: "px-3 py-1.5 text-sm bg-gray-600 text-white hover:bg-gray-700",
    md: "px-4 py-2 text-sm bg-gray-600 text-white hover:bg-gray-700",
    lg: "px-6 py-3 text-base bg-gray-600 text-white hover:bg-gray-700"
  },
  outline: {
    sm: "px-3 py-1.5 text-sm border border-gray-300 text-gray-700 hover:bg-gray-50",
    md: "px-4 py-2 text-sm border border-gray-300 text-gray-700 hover:bg-gray-50",
    lg: "px-6 py-3 text-base border border-gray-300 text-gray-700 hover:bg-gray-50"
  }
};
var UniversalExportButton = ({
  exportService,
  moduleId,
  businessId,
  availableFields,
  dataSource,
  defaultConfig,
  buttonText = "\u5BFC\u51FA\u6570\u636E",
  variant = "primary",
  size = "md",
  disabled = false,
  className = "",
  onExportSuccess,
  onExportError,
  onConfigSave
}) => {
  const [showConfigEditor, setShowConfigEditor] = useState(false);
  const [showDropdown, setShowDropdown] = useState(false);
  const [isExporting, setIsExporting] = useState(false);
  const [exportProgress, setExportProgress] = useState(null);
  const [savedConfigs, setSavedConfigs] = useState([]);
  const loadSavedConfigs = useCallback(async () => {
    try {
      if (exportService) {
        const configs = await exportService.getConfigsByModule(moduleId, businessId);
        setSavedConfigs(configs);
      }
    } catch (error) {
      console.error("\u52A0\u8F7D\u4FDD\u5B58\u7684\u914D\u7F6E\u5931\u8D25:", error);
    }
  }, [exportService, moduleId, businessId]);
  React.useEffect(() => {
    loadSavedConfigs();
  }, [loadSavedConfigs]);
  const handleExport = useCallback(async (config) => {
    console.log("\u{1F680} [UniversalExportButton] \u5F00\u59CB\u5BFC\u51FA:", {
      configId: config.id,
      configName: config.name,
      format: config.format,
      fieldsCount: config.fields.length
    });
    if (!exportService) {
      console.error("\u274C [UniversalExportButton] \u5BFC\u51FA\u670D\u52A1\u672A\u521D\u59CB\u5316");
      onExportError?.("\u5BFC\u51FA\u670D\u52A1\u672A\u521D\u59CB\u5316");
      return;
    }
    setIsExporting(true);
    setExportProgress(null);
    try {
      console.log("\u{1F4CA} [UniversalExportButton] \u83B7\u53D6\u6570\u636E...");
      const data = await dataSource();
      console.log("\u2705 [UniversalExportButton] \u6570\u636E\u83B7\u53D6\u6210\u529F:", {
        dataType: typeof data,
        isArray: Array.isArray(data),
        length: Array.isArray(data) ? data.length : "N/A"
      });
      const request = {
        configId: config,
        dataSource: data,
        // 传递实际数据而不是函数
        queryParams: void 0,
        fieldMapping: void 0,
        filters: void 0,
        sortBy: void 0,
        pagination: void 0,
        customFileName: void 0
      };
      console.log("\u{1F4DE} [UniversalExportButton] \u8C03\u7528\u5BFC\u51FA\u670D\u52A1...");
      const result = await exportService.exportData(request);
      console.log("\u2705 [UniversalExportButton] \u5BFC\u51FA\u6210\u529F:", {
        fileName: result.fileName,
        fileSize: result.fileSize,
        exportedRows: result.exportedRows
      });
      const progress = {
        exportId: result.exportId,
        status: "completed",
        progress: 100,
        processedRows: result.exportedRows,
        totalRows: result.exportedRows,
        startTime: result.startTime,
        estimatedEndTime: result.endTime
      };
      setExportProgress(progress);
      if (result.fileUrl) {
        console.log("\u{1F4E5} [UniversalExportButton] \u4ECEURL\u4E0B\u8F7D\u6587\u4EF6...");
        const link = document.createElement("a");
        link.href = result.fileUrl;
        link.download = result.fileName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        console.log("\u2705 [UniversalExportButton] \u6587\u4EF6\u4E0B\u8F7D\u5B8C\u6210");
      } else if (result.fileBlob) {
        console.log("\u{1F4E5} [UniversalExportButton] \u4ECEBlob\u4E0B\u8F7D\u6587\u4EF6...");
        const url = window.URL.createObjectURL(result.fileBlob);
        const link = document.createElement("a");
        link.href = url;
        link.download = result.fileName;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        window.URL.revokeObjectURL(url);
        console.log("\u2705 [UniversalExportButton] \u6587\u4EF6\u4E0B\u8F7D\u5B8C\u6210");
      }
      setTimeout(() => {
        setIsExporting(false);
        setExportProgress(null);
      }, 1e3);
      onExportSuccess?.(result);
    } catch (error) {
      console.error("\u274C [UniversalExportButton] \u5BFC\u51FA\u5F02\u5E38:", error);
      setIsExporting(false);
      setExportProgress(null);
      let errorMessage = "\u5BFC\u51FA\u5931\u8D25";
      if (error && typeof error === "object") {
        if ("message" in error && typeof error.message === "string") {
          errorMessage = error.message;
        } else if ("code" in error && "message" in error) {
          errorMessage = error.code + ": " + error.message;
        }
      } else if (typeof error === "string") {
        errorMessage = error;
      }
      onExportError?.(errorMessage);
    }
  }, [exportService, dataSource, onExportSuccess, onExportError]);
  const handleQuickExport = useCallback(async () => {
    if (defaultConfig) {
      await handleExport(defaultConfig);
    } else {
      const config = {
        id: "quick_export",
        name: "\u5FEB\u901F\u5BFC\u51FA",
        description: "\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E\u5FEB\u901F\u5BFC\u51FA",
        format: "csv",
        fields: availableFields.map((field, index) => ({
          ...field,
          enabled: true,
          sortOrder: index
        })),
        fileNameTemplate: "\u5BFC\u51FA\u6570\u636E_{date}",
        includeHeader: true,
        delimiter: ",",
        encoding: "utf-8",
        addBOM: true,
        createdAt: /* @__PURE__ */ new Date(),
        updatedAt: /* @__PURE__ */ new Date(),
        moduleId,
        businessId
      };
      await handleExport(config);
    }
  }, [defaultConfig, availableFields, moduleId, businessId, handleExport]);
  const handleConfigSave = useCallback(async (config) => {
    try {
      if (exportService) {
        const savedConfig = await exportService.createConfig(config);
        await loadSavedConfigs();
        onConfigSave?.(savedConfig);
      }
      setShowConfigEditor(false);
    } catch (error) {
      onExportError?.(error instanceof Error ? error.message : "\u4FDD\u5B58\u914D\u7F6E\u5931\u8D25");
    }
  }, [exportService, onConfigSave, onExportError, loadSavedConfigs]);
  const renderProgress = () => {
    if (!exportProgress) return null;
    const { status, progress, processedRows, totalRows } = exportProgress;
    return /* @__PURE__ */ React.createElement("div", { className: "absolute top-full left-0 right-0 mt-2 bg-white border border-gray-200 rounded-lg shadow-lg p-4 z-[10]" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-3 mb-2" }, /* @__PURE__ */ React.createElement(Loader2, { className: "w-4 h-4 animate-spin text-blue-600" }), /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium text-gray-900" }, status === "processing" ? "\u6B63\u5728\u5BFC\u51FA..." : "\u5BFC\u51FA\u5B8C\u6210")), /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between text-xs text-gray-600" }, /* @__PURE__ */ React.createElement("span", null, "\u8FDB\u5EA6: ", progress, "%"), /* @__PURE__ */ React.createElement("span", null, processedRows, " / ", totalRows, " \u884C")), /* @__PURE__ */ React.createElement("div", { className: "w-full bg-gray-200 rounded-full h-2" }, /* @__PURE__ */ React.createElement(
      "div",
      {
        className: "bg-blue-600 h-2 rounded-full transition-all duration-300",
        style: { width: progress + "%" }
      }
    ))));
  };
  const renderDropdown = () => {
    if (!showDropdown) return null;
    return /* @__PURE__ */ React.createElement("div", { className: "absolute top-full left-0 mt-2 bg-white border border-gray-200 rounded-lg shadow-lg py-2 z-[10] min-w-48" }, /* @__PURE__ */ React.createElement(
      "button",
      {
        onClick: () => {
          setShowDropdown(false);
          handleQuickExport();
        },
        disabled: isExporting,
        className: "w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
      },
      /* @__PURE__ */ React.createElement(Download, { className: "w-4 h-4" }),
      "\u5FEB\u901F\u5BFC\u51FA"
    ), savedConfigs.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "border-t border-gray-200 my-1" }), savedConfigs.map((config) => /* @__PURE__ */ React.createElement(
      "button",
      {
        key: config.id,
        onClick: () => {
          setShowDropdown(false);
          handleExport(config);
        },
        disabled: isExporting,
        className: "w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
      },
      /* @__PURE__ */ React.createElement(FileText, { className: "w-4 h-4" }),
      config.name
    ))), /* @__PURE__ */ React.createElement("div", { className: "border-t border-gray-200 my-1" }), /* @__PURE__ */ React.createElement(
      "button",
      {
        onClick: () => {
          setShowDropdown(false);
          setShowConfigEditor(true);
        },
        className: "w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
      },
      /* @__PURE__ */ React.createElement(Settings, { className: "w-4 h-4" }),
      "\u81EA\u5B9A\u4E49\u914D\u7F6E"
    ));
  };
  const buttonStyle = BUTTON_STYLES[variant][size];
  const baseClasses = "inline-flex items-center gap-2 rounded-lg font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed " + buttonStyle;
  return /* @__PURE__ */ React.createElement("div", { className: clsx("relative", className) }, /* @__PURE__ */ React.createElement(
    "button",
    {
      onClick: () => setShowDropdown(!showDropdown),
      disabled: disabled || isExporting,
      className: clsx(baseClasses, isExporting ? "cursor-not-allowed" : "")
    },
    isExporting ? /* @__PURE__ */ React.createElement(Loader2, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ React.createElement(Download, { className: "w-4 h-4" }),
    /* @__PURE__ */ React.createElement("span", null, isExporting ? "\u5BFC\u51FA\u4E2D..." : buttonText),
    /* @__PURE__ */ React.createElement(ChevronDown, { className: "w-4 h-4" })
  ), renderDropdown(), renderProgress(), /* @__PURE__ */ React.createElement(
    ExportConfigEditor,
    {
      moduleId,
      businessId,
      availableFields,
      onSave: handleConfigSave,
      onCancel: () => setShowConfigEditor(false),
      visible: showConfigEditor,
      onConfigChange: loadSavedConfigs
    }
  ), showDropdown && /* @__PURE__ */ React.createElement(
    "div",
    {
      className: "fixed inset-0 z-[0]",
      onClick: () => setShowDropdown(false)
    }
  ));
};

export { API_BASE_PATH, API_ENDPOINTS, DEFAULT_ADD_BOM, DEFAULT_CONFIG_CACHE_TTL, DEFAULT_CSV_DELIMITER, DEFAULT_ENCODING, DEFAULT_EXPORT_FORMAT, DEFAULT_EXPORT_TIMEOUT, DEFAULT_FORMATTERS, DEFAULT_MAX_CONCURRENT_EXPORTS, DEFAULT_MAX_FILE_SIZE, DEFAULT_MAX_ROWS, DEFAULT_RESULT_CACHE_TTL, ERROR_CODES, EXPORT_FORMAT_EXTENSIONS, EXPORT_FORMAT_MIME_TYPES, ExportConfigEditor, UNIVERSAL_EXPORT_NAME, UNIVERSAL_EXPORT_VERSION, UniversalExportButton, UniversalExportClient, applyFormatter, createExportClient, createExportError, escapeCSVField, estimateEndTime, formatDuration, formatErrorMessage, formatFileSize, generateExportFileName, getNestedValue, parseCSVField, sanitizeFileName, setNestedValue, universalExportClient, validateExportConfig, validateExportRequest, validateFileName };
//# sourceMappingURL=chunk-TGNUEULF.mjs.map
//# sourceMappingURL=chunk-TGNUEULF.mjs.map