import * as XLSX from "xlsx";

/**
 * 通用Excel导出 composable
 *
 * 用法：
 * const { exportExcel } = useExportExcel()
 *
 * exportExcel({
 *   fileName: "文件名",
 *   sheets: [
 *     {
 *       name: "Sheet名称",
 *       type: "kv",        // kv=键值对表单, table=表格数据
 *       title: "大标题",    // 可选，仅kv模式
 *       data: ...           // kv模式: [[key, value], ...], table模式: [对象数组]
 *       columns: [...]      // 仅table模式: [{ prop, label, formatter? }]
 *       colWidths: [...]    // 可选: [20, 30, ...]
 *     }
 *   ]
 * })
 */

const buildKvSheet = (config) => {
  const rows = config.title ? [[config.title], []] : [];
  config.data.forEach((row) => rows.push(row));
  const ws = XLSX.utils.aoa_to_sheet(rows);
  if (config.colWidths) {
    ws["!cols"] = config.colWidths.map((w) => ({ wch: w }));
  } else {
    ws["!cols"] = [{ wch: 30 }, { wch: 40 }];
  }
  if (config.title) {
    const lastCol = String.fromCharCode(65 + (config.colWidths?.length || 2) - 1);
    ws["!merges"] = [XLSX.utils.decode_range(`A1:${lastCol}1`)];
  }
  return ws;
};

const buildTableSheet = (config) => {
  const header = config.columns.map((c) => c.label);
  const rows = [header];
  (config.data || []).forEach((item) => {
    rows.push(
      config.columns.map((col) => {
        const val = col.prop.split(".").reduce((o, k) => o?.[k], item);
        return col.formatter ? col.formatter(val, item) : val ?? "";
      })
    );
  });
  const ws = XLSX.utils.aoa_to_sheet(rows);
  if (config.colWidths) {
    ws["!cols"] = config.colWidths.map((w) => ({ wch: w }));
  } else {
    ws["!cols"] = config.columns.map((col) => ({
      wch: Math.max((col.label || "").length * 2.5, 12),
    }));
  }
  return ws;
};

export function useExportExcel() {
  const exportExcel = ({ fileName, sheets = [] }) => {
    const wb = XLSX.utils.book_new();
    sheets.forEach((sheet) => {
      const ws =
        sheet.type === "kv"
          ? buildKvSheet(sheet)
          : buildTableSheet(sheet);
      XLSX.utils.book_append_sheet(wb, ws, sheet.name || "Sheet1");
    });
    XLSX.writeFile(wb, `${fileName}.xlsx`);
  };

  return { exportExcel };
}
