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

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.alibaba.fastjson.JSON;
import com.yd.oss.feign.result.ImportResult;
import com.yd.oss.feign.result.ValidationResult;
import com.yd.oss.service.service.ExcelImportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.*;

/**
 * 通用Excel导入工具类
 * 支持动态表头解析
 */
@Slf4j
@Service
public class ExcelImportServiceImpl implements ExcelImportService {

    /**
     * 通用Excel导入
     * @param file Excel文件
     * @param headerRow 表头行号（默认第1行，从0开始）
     * @param dataStartRow 数据开始行号（默认第2行，从0开始）
     * @param requiredFields 必填字段列表
     * @return 导入结果
     */
    @Override
    public ImportResult genericImport(MultipartFile file,
                                      Integer headerRow,
                                      Integer dataStartRow,
                                      List<String> requiredFields,Integer checkStartRow) {

        ImportResult result = new ImportResult();

        log.info("开始导入Excel，文件名：{}，headerRow：{}，dataStartRow：{}",
                file.getOriginalFilename(), headerRow, dataStartRow);

        try {
            // 参数默认值处理
            int headerRowNum = headerRow != null ? headerRow : 0;
            int dataStartRowNum = dataStartRow != null ? dataStartRow : 1;

            log.info("实际参数：headerRowNum={}, dataStartRowNum={}", headerRowNum, dataStartRowNum);

            // 1. 获取表头信息
            List<String> headers = getExcelHeaders(file, headerRowNum);
            log.info("获取到表头：{}", headers);
            result.setHeaders(headers);

            // 2. 导入Excel数据
            ExcelImportResult<Map<String, Object>> importResult =
                    importExcel(file, headerRowNum, dataStartRowNum);

            // 3. 处理导入结果
            List<Map<String, Object>> data =
                    processImportResult(importResult, headers);
            log.info("处理后数据行数：{}", data.size());
            result.setData(data);
            result.setTotalCount(data.size());

            // 4. 数据验证
            if (requiredFields != null && !requiredFields.isEmpty()) {
                ValidationResult validationResult =
                        validateData(data, requiredFields, dataStartRowNum,checkStartRow);  // 传入dataStartRowNum
                result.setValid(validationResult.isValid());
                result.setErrorMessages(validationResult.getErrors());
            } else {
                result.setValid(true);
            }

            result.setSuccess(true);
            result.setMessage("导入成功，共导入" + data.size() + "条数据");

        } catch (Exception e) {
            log.error("Excel导入失败", e);
            result.setSuccess(false);
            String errorMsg = e.getMessage();
            if (errorMsg == null || errorMsg.isEmpty()) {
                errorMsg = e.getClass().getSimpleName();
            }
            result.setMessage("导入失败：" + errorMsg);
        }

        return result;
    }

    /**
     * 简化的导入方法（使用默认参数）
     * @param file
     * @return
     */
    @Override
    public ImportResult simpleImport(MultipartFile file) {
        return genericImport(file, 0, 1, null,null);
    }

    /**
     * 通用Excel导入方法
     * @param file Excel文件
     * @param headerRowNum 表头所在行号（从0开始）
     * @param dataStartRowNum 数据开始行号（从0开始）
     * @return 导入结果
     */
    public static ExcelImportResult<Map<String, Object>> importExcel(
            MultipartFile file,
            int headerRowNum,
            int dataStartRowNum) throws Exception {

        // 检查文件是否为空
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }

        // 检查文件格式
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null ||
                (!originalFilename.endsWith(".xlsx") && !originalFilename.endsWith(".xls"))) {
            throw new IllegalArgumentException("仅支持Excel文件(.xlsx, .xls)");
        }

        ImportParams params = new ImportParams();
        params.setHeadRows(headerRowNum + 1); // 表头行数
        params.setStartRows(0); // 数据开始行
        params.setNeedVerify(true); // 需要校验

        try {
            // 使用Map接收数据
            return ExcelImportUtil.importExcelMore(
                    file.getInputStream(),
                    Map.class,
                    params
            );
        } catch (Exception e) {
            log.error("Excel导入失败，文件：{}，headerRow：{}，dataStartRow：{}",
                    originalFilename, headerRowNum, dataStartRowNum, e);
            throw new RuntimeException("Excel解析失败：" + e.getMessage(), e);
        }
    }

    /**
     * 获取Excel表头信息
     * @param file Excel文件
     * @param headerRowNum 表头所在行号（从0开始）
     * @return 表头字段列表
     */
    public static List<String> getExcelHeaders(MultipartFile file, int headerRowNum) throws Exception {
        List<String> headers = new ArrayList<>();

        // 修正：使用WorkbookFactory.create()静态方法
        try (Workbook workbook = WorkbookFactory.create(file.getInputStream())) {
            Sheet sheet = workbook.getSheetAt(0);
            Row headerRow = sheet.getRow(headerRowNum);

            if (headerRow != null) {
                for (Cell cell : headerRow) {
                    String headerValue = getCellValue(cell);
                    if (headerValue != null && !headerValue.trim().isEmpty()) {
                        headers.add(headerValue.trim());
                    }
                }
            }
        }
        return headers;
    }

    /**
     * 获取单元格值
     * @param cell
     * @return
     */
    public static String getCellValue(Cell cell) {
        if (cell == null) {
            return null;
        }

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                return String.valueOf(cell.getNumericCellValue());
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }

    /**
     * 处理导入结果，转换为更友好的数据结构，并过滤空行
     * @param result 导入结果
     * @param headers 表头信息
     * @return 处理后的数据
     */
    public static List<Map<String, Object>> processImportResult(
            ExcelImportResult<Map<String, Object>> result,
            List<String> headers) {

        List<Map<String, Object>> processedData = new ArrayList<>();

        if (result != null && result.getList() != null) {
            for (Map<String, Object> rowData : result.getList()) {
                // 检查是否为空行
                if (isEmptyRow(rowData, headers)) {
                    continue; // 跳过空行
                }

                Map<String, Object> processedRow = new LinkedHashMap<>();

                // 按照表头顺序重新组织数据
                for (String header : headers) {
                    processedRow.put(header, rowData.get(header));
                }

                processedData.add(processedRow);
            }
        }

        return processedData;
    }

    /**
     * 判断一行数据是否为空行（更严格的条件）
     */
    private static boolean isEmptyRow(Map<String, Object> rowData, List<String> headers) {
        if (rowData == null || rowData.isEmpty()) {
            return true;
        }

        // 方法1：检查所有业务字段是否都为空
        for (String header : headers) {
            Object value = rowData.get(header);
            if (value != null) {
                String strValue = value.toString().trim();
                // 排除常见的空值表示
                if (!strValue.isEmpty() &&
                        !strValue.equals("-") &&
                        !strValue.equals("null") &&
                        !strValue.equals("NULL")) {
                    return false;
                }
            }
        }

        // 方法2：检查所有键值对（包括系统字段）
        int validCount = 0;
        for (Map.Entry<String, Object> entry : rowData.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            // 跳过系统字段
            if (key.equals("excelRowNum") || key.startsWith("_")) {
                continue;
            }

            if (value != null) {
                String strValue = value.toString().trim();
                if (!strValue.isEmpty()) {
                    validCount++;
                }
            }
        }

        return validCount == 0;
    }

    /**
     * 验证导入数据
     * @param data 导入的数据
     * @param requiredFields 必填字段
     * @return 验证结果
     */
    public static ValidationResult validateData(List<Map<String, Object>> data,
                                                List<String> requiredFields,
                                                int dataStartRow,Integer checkStartRow) {  // 新增参数
        ValidationResult result = new ValidationResult();
        result.setValid(true);

        for (int i = 0; i < data.size(); i++) {
            Map<String, Object> row = data.get(i);
//            int excelRowNum = dataStartRow + i + 1; // 计算Excel中的实际行号
            Integer excelRowNum = checkStartRow + i - 1; // 计算Excel中的实际行号

            // 检查必填字段
            for (String field : requiredFields) {
                Object value = row.get(field);
                if (value == null || value.toString().trim().isEmpty()) {
                    result.setValid(false);
                    result.getErrors().add("第" + excelRowNum + "行，字段[" + field + "]不能为空");
                }
            }
        }
        return result;
    }

}