package digital.laboratory.platform.entrustment.utils;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.*;

/**
 * @author ChenJiangBao
 * @version 1.0
 * @description: 使用 Apache POI 来读取 Excel 文件
 * @date 2025/4/16 9:55
 */
public class ExcelUtils {

    /**
     * 读取 Excel 文件并将其内容转化为 List<Map<String, String>> 的格式
     * 每一行数据是一个 Map，键是列头（表头），值是该单元格的数据。
     *
     * @param file 上传的 Excel 文件
     * @return 解析后的 Excel 数据列表
     * @throws Exception 可能抛出的异常，如文件读取异常
     */
    public static List<Map<String, String>> readExcel(MultipartFile file, int headIndex) throws Exception {
        // 存储最终结果，每一行的 Excel 数据以 Map 的形式存储
        List<Map<String, String>> result = new ArrayList<>();

        // 使用 try-with-resources 语法自动关闭流
        try (InputStream is = file.getInputStream(); // 获取文件输入流
             Workbook workbook = new XSSFWorkbook(is)) { // 使用 XSSFWorkbook 读取 Excel 文件（.xlsx 格式）

            // 获取第一个工作表
            Sheet sheet = workbook.getSheetAt(0);
            if (sheet == null) return result; // 如果没有工作表，则返回空列表

            // 获取表头（第一行），表头行存储列名
            Row headerRow = sheet.getRow(headIndex);
            if (headerRow == null) return result; // 如果没有表头，则返回空列表

            // 存储表头列名
            List<String> headers = new ArrayList<>();
            for (Cell cell : headerRow) {
                // 去除表头列名的多余空格
                headers.add(cell.getStringCellValue().trim());
            }

            // 从第二行开始读取数据
            for (int i = headIndex + 1; i <= sheet.getLastRowNum(); i++) {
                // 获取当前行
                Row row = sheet.getRow(i);
                if (row == null) continue; // 如果当前行为空，则跳过

                // 存储当前行数据的 Map，键是表头，值是单元格数据
                Map<String, String> rowData = new LinkedHashMap<>();
                for (int j = 0; j < headers.size(); j++) {
                    // 获取当前单元格
                    Cell cell = row.getCell(j);
                    // 将列名和单元格数据放入 Map 中
                    rowData.put(headers.get(j), getCellValue(cell));
                }
                // 将当前行的 Map 加入到结果列表中
                result.add(rowData);
            }
        }

        return result; // 返回解析后的数据列表
    }

    /**
     * 获取单元格的值，处理不同类型的单元格
     *
     * @param cell 当前单元格
     * @return 单元格中的值
     */
    private static String getCellValue(Cell cell) {
        if (cell == null) return ""; // 如果单元格为空，返回空字符串

        // 根据单元格的类型来处理其值
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim(); // 字符串类型，返回去除空格后的字符串
            case NUMERIC:
                // 数字类型，判断是否为日期格式
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString(); // 返回日期的字符串表示
                }
                return String.valueOf((long) cell.getNumericCellValue()); // 返回数字
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue()); // 布尔值类型，返回布尔值的字符串表示
            case FORMULA:
                return cell.getCellFormula(); // 公式类型，返回公式的字符串表示
            default:
                return ""; // 其他类型返回空字符串
        }
    }
}
