package com.yd.oss.service.service.impl;

import com.alibaba.fastjson2.JSON;
import com.yd.oss.feign.annotation.ExcelCollection;
import com.yd.oss.feign.annotation.ExcelField;
import com.yd.oss.feign.annotation.ExcelSheet;
import com.yd.oss.service.service.ExcelParserService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Excel通用解析器
 */
@Service
public class ExcelParserServiceImpl implements ExcelParserService {

    private static final Logger log = LoggerFactory.getLogger(ExcelParserServiceImpl.class);

    /**
     * 解析Excel文件（多Sheet页版本）
     */
    @Override
    public Map<Integer, Object> parseExcelWithMultipleSheets(MultipartFile file, Class<?>... sheetClasses) throws Exception {
        Map<Integer, Object> resultMap = new HashMap<>();
        Workbook workbook = WorkbookFactory.create(file.getInputStream());

        try {
            for (Class<?> clazz : sheetClasses) {
                ExcelSheet sheetAnnotation = clazz.getAnnotation(ExcelSheet.class);
                if (sheetAnnotation == null) {
                    log.warn("类 {} 缺少@ExcelSheet注解，跳过处理", clazz.getSimpleName());
                    continue;
                }

                Sheet sheet = getSheet(workbook, sheetAnnotation);
                if (sheet == null) {
                    log.warn("Sheet {} 不存在",
                            !sheetAnnotation.sheetName().isEmpty() ?
                                    sheetAnnotation.sheetName() : sheetAnnotation.sheetIndex());
                    continue;
                }

                Object instance = clazz.getDeclaredConstructor().newInstance();

                // 解析普通字段
                parseFieldsWithMergedCells(sheet, instance);

                // 解析集合字段
                parseCollectionFields(sheet, instance);

                log.info("解析结果: {}", JSON.toJSONString(instance));
                resultMap.put(sheetAnnotation.sheetIndex(), instance);
            }

            return resultMap;
        } finally {
            workbook.close();
        }
    }

    /**
     * 解析单个Sheet页
     */
    public <T> T parseExcel(MultipartFile file, Class<T> clazz) throws Exception {
        Workbook workbook = WorkbookFactory.create(file.getInputStream());
        try {
            ExcelSheet sheetAnnotation = clazz.getAnnotation(ExcelSheet.class);
            Sheet sheet = getSheet(workbook, sheetAnnotation);

            if (sheet == null) {
                throw new RuntimeException("Sheet not found");
            }

            T instance = clazz.getDeclaredConstructor().newInstance();
            parseFieldsWithMergedCells(sheet, instance);
            parseCollectionFields(sheet, instance);

            return instance;
        } finally {
            workbook.close();
        }
    }

    /**
     * 获取Sheet
     */
    private Sheet getSheet(Workbook workbook, ExcelSheet sheetAnnotation) {
        if (sheetAnnotation == null) {
            return workbook.getSheetAt(0);
        }

        if (!sheetAnnotation.sheetName().isEmpty()) {
            Sheet sheet = workbook.getSheet(sheetAnnotation.sheetName());
            if (sheet != null) return sheet;
        }

        return workbook.getSheetAt(sheetAnnotation.sheetIndex());
    }

    /**
     * 处理合并单元格的字段解析
     */
    private void parseFieldsWithMergedCells(Sheet sheet, Object instance) {
        List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();

        for (Field field : instance.getClass().getDeclaredFields()) {
            ExcelField excelField = field.getAnnotation(ExcelField.class);
            if (excelField != null) {
                try {
                    int valueRow = excelField.valueRow() >= 0 ? excelField.valueRow() : excelField.titleRow();
                    int valueCol = excelField.valueCol() >= 0 ? excelField.valueCol() : excelField.titleCol() + 1;

                    Row row = sheet.getRow(valueRow);
                    if (row == null) continue;

                    // 检查是否为合并单元格
                    CellRangeAddress mergedRegion = findMergedRegion(mergedRegions, valueRow, valueCol);

                    String cellValue;
                    if (mergedRegion != null) {
                        // 合并单元格，取第一个单元格的值
                        Cell firstCell = sheet.getRow(mergedRegion.getFirstRow())
                                .getCell(mergedRegion.getFirstColumn());
                        cellValue = getCellValueAsString(firstCell);
                    } else {
                        // 普通单元格
                        Cell cell = row.getCell(valueCol);
                        cellValue = cell != null ? getCellValueAsString(cell) : null;
                    }

                    if (cellValue == null || cellValue.trim().isEmpty()) {
                        continue;
                    }

                    // 转换单元格值
                    Object value = convertStringValue(cellValue, field.getType(), excelField.dateFormat());

                    // 设置字段值
                    field.setAccessible(true);
                    field.set(instance, value);
                } catch (Exception e) {
                    log.warn("设置字段 {} 值失败: {}", field.getName(), e.getMessage());
                }
            }
        }
    }

    /**
     * 查找包含指定行列的合并区域
     */
    private CellRangeAddress findMergedRegion(List<CellRangeAddress> mergedRegions, int row, int column) {
        for (CellRangeAddress region : mergedRegions) {
            if (region.isInRange(row, column)) {
                return region;
            }
        }
        return null;
    }

    /**
     * 解析集合字段（支持固定行跨度模式）
     */
    private void parseCollectionFields(Sheet sheet, Object instance) throws Exception {
        for (Field field : instance.getClass().getDeclaredFields()) {
            ExcelCollection collectionAnnotation = field.getAnnotation(ExcelCollection.class);
            if (collectionAnnotation != null) {
                List<Object> collectionData = new ArrayList<>();
                Class<?> collectionType = collectionAnnotation.type();

                log.info("开始解析集合字段: {}, 类型: {}, 起始行: {}, 分组模式: {}",
                        field.getName(), collectionType.getSimpleName(),
                        collectionAnnotation.startRow(), collectionAnnotation.groupMode());

                // 获取目标类的所有字段及其Excel注解
                Map<Field, ExcelField> fieldMappings = new HashMap<>();
                for (Field elementField : collectionType.getDeclaredFields()) {
                    ExcelField excelField = elementField.getAnnotation(ExcelField.class);
                    if (excelField != null) {
                        fieldMappings.put(elementField, excelField);
                    }
                }

                if (collectionAnnotation.groupMode() == ExcelCollection.GroupMode.FIXED_ROW_SPAN) {
                    // 固定行跨度模式 - 每个元素占用固定行数
                    parseFixedRowSpanCollection(sheet, collectionData, collectionType,
                            fieldMappings, collectionAnnotation);
                } else {
                    // 单行模式 - 每个元素占用一行
                    parseSingleRowCollection(sheet, collectionData, collectionType,
                            fieldMappings, collectionAnnotation);
                }

                // 设置集合字段值
                field.setAccessible(true);
                field.set(instance, collectionData);
                log.info("集合字段 {} 解析完成，共 {} 条数据", field.getName(), collectionData.size());
            }
        }
    }

    /**
     * 解析固定行跨度的集合（支持结束标志字段和下一个字段标题）
     */
    private void parseFixedRowSpanCollection(Sheet sheet, List<Object> collectionData,
                                             Class<?> collectionType,
                                             Map<Field, ExcelField> fieldMappings,
                                             ExcelCollection collectionAnnotation) throws Exception {
        int rowSpan = collectionAnnotation.rowSpan();
        int startRow = collectionAnnotation.startRow();
        String endFlagField = collectionAnnotation.endFlagField();
        String nextFieldTitle = collectionAnnotation.nextFieldTitle();

        log.info("开始解析固定行跨度集合，起始行: {}, 行跨度: {}, 结束标志字段: {}, 下一字段标题: {}",
                startRow, rowSpan, endFlagField, nextFieldTitle);

        // 获取结束标志字段的映射信息
        Field endFlagFieldObj = null;
        ExcelField endFlagExcelField = null;
        if (!endFlagField.isEmpty()) {
            try {
                endFlagFieldObj = collectionType.getDeclaredField(endFlagField);
                endFlagExcelField = endFlagFieldObj.getAnnotation(ExcelField.class);
                log.info("找到结束标志字段: {}, 位置: 行{}, 列{}",
                        endFlagField, endFlagExcelField.valueRow(), endFlagExcelField.valueCol());
            } catch (NoSuchFieldException e) {
                log.warn("结束标志字段 {} 不存在，将使用默认结束判断", endFlagField);
            }
        }

        // 遍历每个元素组
        for (int groupIndex = 0; groupIndex < 1000; groupIndex++) {
            int groupStartRow = startRow + (groupIndex * rowSpan);
            int nextGroupStartRow = groupStartRow + rowSpan;

            // 检查是否超出表格范围
            if (groupStartRow > sheet.getLastRowNum()) {
                log.info("超出表格范围，集合解析结束");
                break;
            }

            log.debug("=== 解析组 {}，起始行: {} ===", groupIndex + 1, groupStartRow);

            // 关键修改：先解析当前组
            try {
                Object element = collectionType.getDeclaredConstructor().newInstance();
                boolean hasData = parseGroupData(sheet, groupStartRow, element, fieldMappings);

                if (hasData) {
                    collectionData.add(element);
                    log.info("成功解析组 {}，组起始行: {}", groupIndex + 1, groupStartRow);
                } else {
                    log.debug("组起始行 {} 没有有效数据，跳过", groupStartRow);

                    // 如果连续3个组没有数据，认为集合结束
                    if (groupIndex > 0 && !hasDataInNextGroup(sheet, nextGroupStartRow, fieldMappings)) {
                        log.info("检测到连续空组，集合解析结束");
                        break;
                    }
                }

                // 关键修改：在解析当前组后，检查下一个组是否应该结束
                boolean shouldEnd = false;

                // 1. 检查结束标志字段（检查下一个组）
                if (!endFlagField.isEmpty() && endFlagExcelField != null) {
                    if (shouldEndByEndFlag(sheet, nextGroupStartRow, rowSpan, endFlagExcelField)) {
                        log.info("检测到下一个组结束标志为空，集合解析结束");
                        shouldEnd = true;
                    }
                }

                // 2. 检查下一个对象的第一个字段标题
                if (!shouldEnd && nextFieldTitle != null && !nextFieldTitle.isEmpty()) {
                    if (shouldEndByNextFieldTitle(sheet, nextGroupStartRow, fieldMappings, nextFieldTitle)) {
                        log.info("检测到下一个对象标题 '{}'，集合解析结束", nextFieldTitle);
                        shouldEnd = true;
                    }
                }

                if (shouldEnd) {
                    break;
                }

            } catch (Exception e) {
                log.error("解析组起始行 {} 时发生异常: {}", groupStartRow, e.getMessage(), e);
            }
        }

        log.info("固定行跨度集合解析完成，共解析 {} 个元素", collectionData.size());
    }

    /**
     * 根据下一个对象的第一个字段标题判断是否应该结束集合解析
     */
    private boolean shouldEndByNextFieldTitle(Sheet sheet, int nextGroupStartRow,
                                              Map<Field, ExcelField> fieldMappings,
                                              String expectedNextFieldTitle) {
        try {
            if (expectedNextFieldTitle == null || expectedNextFieldTitle.isEmpty()) {
                return false;
            }

            // 获取第一个字段的标题位置（用于检查下一个对象的标题）
            Field firstField = getFirstFieldByColumnOrder(fieldMappings);
            if (firstField == null) {
                return false;
            }

            ExcelField firstExcelField = fieldMappings.get(firstField);
            int titleRow = firstExcelField.titleRow();
            int titleCol = firstExcelField.titleCol();

            log.debug("检查下一个字段标题: 下一组起始行={}, 标题行={}, 标题列={}, 预期标题='{}'",
                    nextGroupStartRow, titleRow, titleCol, expectedNextFieldTitle);

            // 检查下一组的标题行
            int nextTitleRow = nextGroupStartRow + titleRow;
            if (nextTitleRow > sheet.getLastRowNum()) {
                log.debug("下一组标题行 {} 超出表格范围", nextTitleRow);
                return true;
            }

            Row row = sheet.getRow(nextTitleRow);
            if (row == null) {
                log.debug("下一组标题行 {} 为null", nextTitleRow);
                return true;
            }

            Cell titleCell = row.getCell(titleCol);
            if (titleCell == null) {
                log.debug("下一组标题行{}列{}为null", nextTitleRow, titleCol);
                return true;
            }

            String actualTitle = getCellValueAsString(titleCell);
            log.debug("实际下一组标题: '{}'", actualTitle);

            // 如果下一组的标题与预期下一个对象的标题匹配，说明集合应该结束
            if (expectedNextFieldTitle.equals(actualTitle)) {
                log.info("检测到下一个对象标题 '{}'，集合解析结束", expectedNextFieldTitle);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.warn("检查下一个字段标题失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 按列顺序获取第一个字段（列号最小的字段）
     */
    private Field getFirstFieldByColumnOrder(Map<Field, ExcelField> fieldMappings) {
        if (fieldMappings.isEmpty()) {
            return null;
        }

        return fieldMappings.entrySet().stream()
                .min(Comparator.comparingInt(entry -> entry.getValue().valueCol()))
                .map(Map.Entry::getKey)
                .orElse(null);
    }

    /**
     * 根据结束标志字段判断是否应该结束集合解析
     * 关键修改：检查当前组的结束标志，而不是下一个组
     */
    private boolean shouldEndByEndFlag(Sheet sheet, int currentGroupStartRow,
                                       int rowSpan, ExcelField endFlagExcelField) {
        try {
            // 计算结束标志字段在当前组中的实际位置
            int actualRow = currentGroupStartRow + endFlagExcelField.valueRow();
            int actualCol = endFlagExcelField.valueCol();

            log.debug("检查结束标志: 当前组起始行={}, 实际行={}, 实际列={}",
                    currentGroupStartRow, actualRow, actualCol);

            // 检查行号是否有效
            if (actualRow > sheet.getLastRowNum()) {
                log.debug("结束标志检查: 行号 {} 超出表格范围", actualRow);
                return true;
            }

            Row row = sheet.getRow(actualRow);
            if (row == null) {
                log.debug("结束标志检查: 行 {} 为null", actualRow);
                return true;
            }

            Cell cell = row.getCell(actualCol);
            if (cell == null) {
                log.debug("结束标志检查: 行{}列{}为null", actualRow, actualCol);
                return true;
            }

            String cellValue = getCellValueAsString(cell);
            log.debug("结束标志字段值: '{}'", cellValue);

            // 如果结束标志字段的值为空，说明集合结束
            if (cellValue == null || cellValue.trim().isEmpty()) {
                log.info("结束标志字段为空，集合解析结束");
                return true;
            }

            return false;
        } catch (Exception e) {
            log.warn("检查结束标志失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 获取第一个字段（用于结束判断）
     */
    private Field getFirstField(Map<Field, ExcelField> fieldMappings) {
        if (fieldMappings.isEmpty()) {
            return null;
        }
        return fieldMappings.keySet().iterator().next();
    }

    /**
     * 检查是否应该结束集合解析
     */
    private boolean shouldEndCollection(Sheet sheet, int groupStartRow,
                                        Field firstField, ExcelField excelField,
                                        List<Object> collectionData) {
        try {
            if (firstField == null || excelField == null) {
                return false;
            }

            // 获取上一个对象的第一个字段值
            Object lastElement = collectionData.get(collectionData.size() - 1);
            firstField.setAccessible(true);
            Object lastValue = firstField.get(lastElement);

            // 获取当前组的第一个字段值
            int actualRow = groupStartRow + excelField.valueRow();
            int actualCol = excelField.valueCol();

            if (actualRow > sheet.getLastRowNum()) {
                return true;
            }

            Row row = sheet.getRow(actualRow);
            if (row == null) {
                return true;
            }

            Cell cell = row.getCell(actualCol);
            if (cell == null) {
                return true;
            }

            String currentCellValue = getCellValueAsString(cell);
            Object currentValue = convertStringValue(currentCellValue, firstField.getType(), excelField.dateFormat());

            // 如果当前值与上一个值不同，说明集合结束
            if (!Objects.equals(lastValue, currentValue)) {
                log.debug("第一个字段值发生变化: {} -> {}", lastValue, currentValue);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.warn("检查集合结束标志失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 解析组数据（通用方法）
     */
    private boolean parseGroupData(Sheet sheet, int groupStartRow, Object element,
                                   Map<Field, ExcelField> fieldMappings) throws Exception {
        boolean hasData = false;

        for (Map.Entry<Field, ExcelField> entry : fieldMappings.entrySet()) {
            Field elementField = entry.getKey();
            ExcelField excelField = entry.getValue();

            int actualRow = groupStartRow + excelField.valueRow();
            int actualCol = excelField.valueCol();

            log.debug("字段 {}: 组起始行={}, 相对行={}, 实际行号={}, 列号={}",
                    elementField.getName(), groupStartRow, excelField.valueRow(), actualRow, actualCol);

            // 检查行号是否有效
            if (actualRow > sheet.getLastRowNum()) {
                log.debug("行号 {} 超出表格范围", actualRow);
                continue;
            }

            Row row = sheet.getRow(actualRow);
            if (row == null) {
                log.debug("行 {} 为null，跳过", actualRow);
                continue;
            }

            Cell cell = row.getCell(actualCol);
            if (cell == null) {
                log.debug("行{}列{}为null，跳过", actualRow, actualCol);
                continue;
            }

            String cellValue = getCellValueAsString(cell);
            if (cellValue == null || cellValue.trim().isEmpty()) {
                log.debug("行{}列{}的值为空，跳过", actualRow, actualCol);
                continue;
            }

            log.debug("字段 {}: 行{}列{} = '{}'",
                    elementField.getName(), actualRow, actualCol, cellValue);

            try {
                Object value = convertStringValue(cellValue, elementField.getType(), excelField.dateFormat());
                elementField.setAccessible(true);
                elementField.set(element, value);
                hasData = true;

                log.debug("成功设置字段 {}: {} -> {}", elementField.getName(), cellValue, value);
            } catch (Exception e) {
                log.error("设置字段 {} 值失败，行{}列{}，值'{}': {}",
                        elementField.getName(), actualRow, actualCol, cellValue, e.getMessage());
            }
        }

        return hasData;
    }

    /**
     * 检查下一个组是否有数据
     */
    private boolean hasDataInNextGroup(Sheet sheet, int nextGroupStartRow,
                                       Map<Field, ExcelField> fieldMappings) {
        for (Map.Entry<Field, ExcelField> entry : fieldMappings.entrySet()) {
            ExcelField excelField = entry.getValue();
            int valueCol = excelField.valueCol();

            // 直接使用相对行号
            int actualRow = nextGroupStartRow + excelField.valueRow();

            if (actualRow > sheet.getLastRowNum()) {
                continue;
            }

            Row row = sheet.getRow(actualRow);
            if (row != null) {
                Cell cell = row.getCell(valueCol);
                if (cell != null) {
                    String cellValue = getCellValueAsString(cell);
                    if (cellValue != null && !cellValue.trim().isEmpty()) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 解析单行模式的集合（支持结束标志字段）
     */
    private void parseSingleRowCollection(Sheet sheet, List<Object> collectionData,
                                          Class<?> collectionType,
                                          Map<Field, ExcelField> fieldMappings,
                                          ExcelCollection collectionAnnotation) throws Exception {
        int startRow = collectionAnnotation.startRow();
        String endFlagField = collectionAnnotation.endFlagField();
        String nextFieldTitle = collectionAnnotation.nextFieldTitle();

        log.info("=== 开始解析单行集合 ===");
        log.info("集合类型: {}, 起始行: {}, 结束标志字段: {}, 下一字段标题: {}",
                collectionType.getSimpleName(), startRow, endFlagField, nextFieldTitle);

        // 获取结束标志字段的映射信息
        Field endFlagFieldObj = null;
        ExcelField endFlagExcelField = null;
        if (!endFlagField.isEmpty()) {
            try {
                endFlagFieldObj = collectionType.getDeclaredField(endFlagField);
                endFlagExcelField = endFlagFieldObj.getAnnotation(ExcelField.class);
                log.info("结束标志字段映射: 字段={}, 相对行={}, 列={}",
                        endFlagField, endFlagExcelField.valueRow(), endFlagExcelField.valueCol());
            } catch (NoSuchFieldException e) {
                log.warn("结束标志字段 {} 不存在，将使用默认结束判断", endFlagField);
            }
        }

        // 输出字段映射信息
        log.info("字段映射信息:");
        for (Map.Entry<Field, ExcelField> entry : fieldMappings.entrySet()) {
            Field field = entry.getKey();
            ExcelField excelField = entry.getValue();
            log.info("  {}: 相对行={}, 列={}", field.getName(), excelField.valueRow(), excelField.valueCol());
        }

        // 遍历行，解析集合元素
        int parsedCount = 0;
        for (int rowNum = startRow; rowNum <= sheet.getLastRowNum(); rowNum++) {
            Row row = sheet.getRow(rowNum);

            log.info("--- 检查行 {} ---", rowNum);

            if (row == null) {
                log.info("行 {} 为null，跳过", rowNum);
                continue;
            }

            // 检查结束标志
            boolean shouldEnd = false;
            if (!endFlagField.isEmpty() && endFlagExcelField != null) {
                shouldEnd = shouldEndSingleRowByEndFlag(sheet, rowNum, endFlagExcelField);
                log.info("结束标志检查结果: {}", shouldEnd);
            }

            // 检查下一个字段标题（新增逻辑）
            if (!shouldEnd && nextFieldTitle != null && !nextFieldTitle.isEmpty()) {
                shouldEnd = shouldEndSingleRowByNextFieldTitle(sheet, rowNum, fieldMappings, nextFieldTitle);
                log.info("下一字段标题检查结果: {}", shouldEnd);
            }

            if (shouldEnd) {
                log.info("检测到单行集合结束条件，集合解析结束");
                break;
            }

            try {
                Object element = collectionType.getDeclaredConstructor().newInstance();
                boolean hasData = parseSingleRowData(sheet, rowNum, element, fieldMappings);

                if (hasData) {
                    collectionData.add(element);
                    parsedCount++;
                    log.info("✅ 成功解析单行集合元素，行{}: {}", rowNum, JSON.toJSONString(element));
                } else {
                    log.info("❌ 行 {} 没有有效数据，跳过", rowNum);

                    // 如果连续3行没有数据，认为集合结束
                    if (!hasDataInNextRows(sheet, rowNum + 1, 3, fieldMappings)) {
                        log.info("检测到连续空行，单行集合解析结束");
                        break;
                    }
                }
            } catch (Exception e) {
                log.warn("解析单行集合元素失败，行{}: {}", rowNum, e.getMessage());
            }
        }

        log.info("=== 单行集合解析完成，共解析 {} 个元素 ===", parsedCount);
    }

    /**
     * 检查单行模式是否应该根据下一个字段标题结束
     */
    private boolean shouldEndSingleRowByNextFieldTitle(Sheet sheet, int currentRow,
                                                       Map<Field, ExcelField> fieldMappings,
                                                       String expectedNextFieldTitle) {
        try {
            if (expectedNextFieldTitle == null || expectedNextFieldTitle.isEmpty()) {
                return false;
            }

            // 获取第一个字段的标题位置
            Field firstField = getFirstFieldByColumnOrder(fieldMappings);
            if (firstField == null) {
                return false;
            }

            ExcelField firstExcelField = fieldMappings.get(firstField);
            int titleRow = firstExcelField.titleRow();
            int titleCol = firstExcelField.titleCol();

            // 检查下一行的标题
            int nextTitleRow = currentRow + 1;
            if (nextTitleRow > sheet.getLastRowNum()) {
                return true;
            }

            Row row = sheet.getRow(nextTitleRow);
            if (row == null) {
                return true;
            }

            Cell titleCell = row.getCell(titleCol);
            if (titleCell == null) {
                return true;
            }

            String actualTitle = getCellValueAsString(titleCell);

            // 如果下一行的标题与预期下一个对象的标题匹配，说明集合应该结束
            if (expectedNextFieldTitle.equals(actualTitle)) {
                log.info("检测到单行模式下一个对象标题 '{}'，集合解析结束", expectedNextFieldTitle);
                return true;
            }

            return false;
        } catch (Exception e) {
            log.warn("检查单行模式下一个字段标题失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 检查单行模式是否应该根据结束标志结束
     */
    private boolean shouldEndSingleRowByEndFlag(Sheet sheet, int currentRow,
                                                ExcelField endFlagExcelField) {
        try {
            int actualCol = endFlagExcelField.valueCol();

            log.debug("检查单行结束标志: 行={}, 列={}", currentRow, actualCol);

            Row row = sheet.getRow(currentRow);
            if (row == null) {
                log.debug("结束标志检查: 行 {} 为null", currentRow);
                return true;
            }

            Cell cell = row.getCell(actualCol);
            if (cell == null) {
                log.debug("结束标志检查: 行{}列{}为null", currentRow, actualCol);
                return true;
            }

            String cellValue = getCellValueAsString(cell);
            log.debug("单行结束标志字段值: '{}'", cellValue);

            // 如果结束标志字段的值为空，说明集合结束
            if (cellValue == null || cellValue.trim().isEmpty()) {
                log.info("单行结束标志字段为空，集合解析结束");
                return true;
            }

            return false;
        } catch (Exception e) {
            log.warn("检查单行结束标志失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 解析单行数据
     */
    private boolean parseSingleRowData(Sheet sheet, int rowNum, Object element,
                                       Map<Field, ExcelField> fieldMappings) throws Exception {
        boolean hasData = false;
        Row row = sheet.getRow(rowNum);

        if (row == null) {
            return false;
        }

        for (Map.Entry<Field, ExcelField> entry : fieldMappings.entrySet()) {
            Field elementField = entry.getKey();
            ExcelField excelField = entry.getValue();

            int actualCol = excelField.valueCol();

            log.debug("单行字段 {}: 行={}, 列={}",
                    elementField.getName(), rowNum, actualCol);

            Cell cell = row.getCell(actualCol);
            if (cell == null) {
                log.debug("行{}列{}为null，跳过", rowNum, actualCol);
                continue;
            }

            String cellValue = getCellValueAsString(cell);
            if (cellValue == null || cellValue.trim().isEmpty()) {
                log.debug("行{}列{}的值为空，跳过", rowNum, actualCol);
                continue;
            }

            log.debug("单行字段 {}: 行{}列{} = '{}'",
                    elementField.getName(), rowNum, actualCol, cellValue);

            try {
                Object value = convertStringValue(cellValue, elementField.getType(), excelField.dateFormat());
                elementField.setAccessible(true);
                elementField.set(element, value);
                hasData = true;

                log.debug("成功设置单行字段 {}: {} -> {}", elementField.getName(), cellValue, value);
            } catch (Exception e) {
                log.error("设置单行字段 {} 值失败，行{}列{}，值'{}': {}",
                        elementField.getName(), rowNum, actualCol, cellValue, e.getMessage());
            }
        }

        return hasData;
    }

    /**
     * 检查后续行是否有数据
     */
    private boolean hasDataInNextRows(Sheet sheet, int startRow, int checkRowCount,
                                      Map<Field, ExcelField> fieldMappings) {
        for (int i = 0; i < checkRowCount; i++) {
            int rowNum = startRow + i;
            if (rowNum > sheet.getLastRowNum()) {
                return false;
            }

            Row row = sheet.getRow(rowNum);
            if (row == null) {
                continue;
            }

            for (Map.Entry<Field, ExcelField> entry : fieldMappings.entrySet()) {
                ExcelField excelField = entry.getValue();
                int valueCol = excelField.valueCol();

                Cell cell = row.getCell(valueCol);
                if (cell != null) {
                    String cellValue = getCellValueAsString(cell);
                    if (cellValue != null && !cellValue.trim().isEmpty()) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 自动检测集合的结束行
     */
    private int findCollectionEndRow(Sheet sheet, int startRow) {
        int maxEmptyRows = 3; // 连续空行的最大数量
        int emptyRowCount = 0;
        int lastDataRow = startRow;

        for (int rowNum = startRow; rowNum <= sheet.getLastRowNum(); rowNum++) {
            Row row = sheet.getRow(rowNum);
            if (isRowEmpty(row)) {
                emptyRowCount++;
                if (emptyRowCount >= maxEmptyRows) {
                    return lastDataRow;
                }
            } else {
                emptyRowCount = 0;
                lastDataRow = rowNum;
            }
        }

        return sheet.getLastRowNum();
    }

    /**
     * 将单元格值转换为字符串
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return new SimpleDateFormat("yyyy/MM/dd").format(cell.getDateCellValue());
                } else {
                    // 数字类型避免科学计数法，转换为字符串
                    double numericValue = cell.getNumericCellValue();
                    if (numericValue == (long) numericValue) {
                        return String.valueOf((long) numericValue);
                    } else {
                        return String.valueOf(numericValue);
                    }
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                try {
                    return cell.getStringCellValue().trim();
                } catch (Exception e) {
                    // 公式计算结果不是字符串时，尝试获取数值
                    return String.valueOf(cell.getNumericCellValue());
                }
            default:
                return "";
        }
    }

    /**
     * 字符串值类型转换
     */
    private Object convertStringValue(String value, Class<?> targetType, String dateFormat) {
        if (value == null || value.isEmpty()) return null;

        try {
            if (targetType == String.class) {
                return value;
            } else if (targetType == Integer.class || targetType == int.class) {
                // 处理可能的小数点
                if (value.contains(".")) {
                    return (int) Double.parseDouble(value);
                }
                return Integer.parseInt(value);
            } else if (targetType == Long.class || targetType == long.class) {
                if (value.contains(".")) {
                    return (long) Double.parseDouble(value);
                }
                return Long.parseLong(value);
            } else if (targetType == Double.class || targetType == double.class) {
                return Double.parseDouble(value);
            } else if (targetType == BigDecimal.class) {
                // 特殊处理数值，确保是数值
                try {
                    return new BigDecimal(value);
                } catch (NumberFormatException e) {
                    log.warn("BigDecimal转换失败，尝试清理字符串: {}", value);
                    // 清理非数字字符（保留小数点和负号）
                    String cleanValue = value.replaceAll("[^\\d.-]", "");
                    if (!cleanValue.isEmpty()) {
                        return new BigDecimal(cleanValue);
                    }
                    return null;
                }
            } else if (targetType == Date.class) {
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
                    return sdf.parse(value);
                } catch (ParseException e) {
                    log.warn("日期格式转换失败: {}", value);
                    return null;
                }
            } else if (targetType == Boolean.class || targetType == boolean.class) {
                return "是".equals(value) || "YES".equalsIgnoreCase(value) || "TRUE".equalsIgnoreCase(value) || "1".equals(value);
            }
        } catch (Exception e) {
            log.warn("类型转换失败: 值='{}', 目标类型={}, 错误: {}", value, targetType.getSimpleName(), e.getMessage());
        }

        return null;
    }

    /**
     * 检查行是否为空
     */
    private boolean isRowEmpty(Row row) {
        if (row == null) return true;

        for (Cell cell : row) {
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                String value = getCellValueAsString(cell);
                if (value != null && !value.trim().isEmpty()) {
                    return false;
                }
            }
        }
        return true;
    }
}