const XLSX = require('xlsx');
const ExcelJS = require('exceljs');
const path = require('path');
const fs = require('fs');

class ExportUtils {
  /**
   * 导出数据到Excel文件
   * @param {Array} data - 要导出的数据数组
   * @param {Array} columns - 列定义数组
   * @param {String} filename - 文件名（不含扩展名）
   * @returns {Object} 导出结果
   */
  static exportToExcel(data, columns, filename = 'export') {
    try {
      // 创建工作簿
      const workbook = XLSX.utils.book_new();
      
      // 准备数据
      const worksheetData = [];
      
      // 添加表头
      const headers = columns.map(col => col.title);
      worksheetData.push(headers);
      
      // 添加数据行
      data.forEach(row => {
        const rowData = columns.map(col => {
          const value = row[col.dataIndex] || row[col.key] || '';
          return value;
        });
        worksheetData.push(rowData);
      });
      
      // 创建工作表
      const worksheet = XLSX.utils.aoa_to_sheet(worksheetData);
      
      // 设置列宽
      const colWidths = columns.map(col => ({
        wch: col.width || 15
      }));
      worksheet['!cols'] = colWidths;
      
      // 添加工作表到工作簿
      XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
      
      // 生成文件路径
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const fileName = `${filename}_${timestamp}.xlsx`;
      const filePath = path.join(__dirname, '..', 'uploads', fileName);
      
      // 确保uploads目录存在
      const uploadsDir = path.dirname(filePath);
      if (!fs.existsSync(uploadsDir)) {
        fs.mkdirSync(uploadsDir, { recursive: true });
      }
      
      // 写入文件
      XLSX.writeFile(workbook, filePath);
      
      return {
        success: true,
        filePath: filePath,
        fileName: fileName,
        message: '导出成功'
      };
      
    } catch (error) {
      console.error('导出Excel失败:', error);
      return {
        success: false,
        message: error.message,
        error: error
      };
    }
  }

  /**
   * 导出数据到Excel文件（带样式）
   * @param {Array} data - 要导出的数据数组
   * @param {Array} columns - 列定义数组，包含 required 属性用于标识必填字段
   * @param {String} filename - 文件名（不含扩展名）
   * @returns {Object} 导出结果
   */
  static async exportToExcelWithStyle(data, columns, filename = 'export') {
    try {
      // 使用ExcelJS创建工作簿
      const workbook = new ExcelJS.Workbook();
      const worksheet = workbook.addWorksheet('Sheet1');
      
      // 设置表头
      const headerRow = worksheet.addRow(columns.map(col => col.title));
      
      // 设置表头样式（必填字段为红色，可选字段为黑色）
      headerRow.eachCell((cell, colNumber) => {
        const colIndex = colNumber - 1;
        const col = columns[colIndex];
        
        // 设置表头样式
        cell.font = { bold: true, size: 11 };
        cell.alignment = { vertical: 'middle', horizontal: 'center' };
        cell.fill = {
          type: 'pattern',
          pattern: 'solid',
          fgColor: { argb: 'FFFFFFFF' } // 白色背景
        };
        
        // 必填字段设置为红色字体
        if (col.required) {
          cell.font = { ...cell.font, color: { argb: 'FFFF0000' } }; // 红色
        } else {
          cell.font = { ...cell.font, color: { argb: 'FF000000' } }; // 黑色
        }
        
        // 设置边框
        cell.border = {
          top: { style: 'thin' },
          left: { style: 'thin' },
          bottom: { style: 'thin' },
          right: { style: 'thin' }
        };
      });
      
      // 添加数据行
      data.forEach(row => {
        const rowData = columns.map(col => {
          const value = row[col.dataIndex] || row[col.key] || '';
          return value;
        });
        const dataRow = worksheet.addRow(rowData);
        
        // 设置数据行样式
        dataRow.eachCell((cell) => {
          cell.alignment = { vertical: 'middle', horizontal: 'left' };
          cell.border = {
            top: { style: 'thin' },
            left: { style: 'thin' },
            bottom: { style: 'thin' },
            right: { style: 'thin' }
          };
        });
      });
      
      // 设置列宽
      columns.forEach((col, index) => {
        worksheet.getColumn(index + 1).width = col.width || 15;
      });
      
      // 生成文件路径
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const fileName = `${filename}_${timestamp}.xlsx`;
      const filePath = path.join(__dirname, '..', 'uploads', fileName);
      
      // 确保uploads目录存在
      const uploadsDir = path.dirname(filePath);
      if (!fs.existsSync(uploadsDir)) {
        fs.mkdirSync(uploadsDir, { recursive: true });
      }
      
      // 写入文件
      await workbook.xlsx.writeFile(filePath);
      
      return {
        success: true,
        filePath: filePath,
        fileName: fileName,
        message: '导出成功'
      };
      
    } catch (error) {
      console.error('导出Excel失败:', error);
      return {
        success: false,
        message: error.message,
        error: error
      };
    }
  }
}

module.exports = ExportUtils;
