package com.ruoyi.cms.util.excel;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;

/**
 * 最终版 LongConverter：
 * 1. 正常数字（含单位）→ 正确Long值
 * 2. 面议/无有效数字 → 返回0
 * 3. 保留详细日志，便于排查
 */
public class LongConverter implements Converter<Long> {

    // 需清洗的特殊字符（仅去掉单位/分隔符，保留数字）
    private static final Set<String> CLEAN_CHARS = new HashSet<String>() {{
        add("元");  // 金额单位
        add("/");   // 分隔符
        add("月");  // 时间单位
        add(",");   // 千分位
        add("k");   // 千单位
        add("K");   // 大写K
    }};

    // 需转换为0的特殊文本（可扩展，比如"无"、"面议"等）
    private static final Set<String> SPECIAL_TEXT = new HashSet<String>() {{
        add("面议");
        add("无");
        add("面议薪资");
        add("薪资面议");
    }};

    @Override
    public Class<Long> supportJavaTypeKey() {
        return Long.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    /**
     * 读Excel：核心逻辑（适配「面议」转0）
     */
    @Override
    public Long convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
                                  GlobalConfiguration globalConfiguration) {
        // 1. 优先获取单元格的字符串值（适配所有EasyExcel版本）
        String rawValue = null;
        if (cellData != null) {
            rawValue = cellData.getStringValue();
            // 数值型单元格兜底
            if (StringUtils.isBlank(rawValue) && cellData.getNumberValue() != null) {
                rawValue = cellData.getNumberValue().toString();
            }
        }

        // 2. 空值/空白字符串 → 返回0
        if (StringUtils.isBlank(rawValue)) {
            return 0L;
        }
        String trimmedValue = rawValue.trim();

        // 3. 匹配"面议"等特殊文本 → 直接返回0
        if (SPECIAL_TEXT.contains(trimmedValue)) {
            System.out.printf("【特殊处理】单元格%s，原始值：%s → 转换为0%n",
                    getCellPos(cellData), trimmedValue);
            return 0L;
        }

        // 4. 清洗特殊字符（仅去掉单位/分隔符，保留数字）
        String cleanValue = cleanSpecialChars(trimmedValue);
        // 清洗后无有效数字 → 返回0
        if (StringUtils.isBlank(cleanValue)) {
            System.err.printf("【无有效数字】单元格%s，原始值：%s → 转换为0%n",
                    getCellPos(cellData), trimmedValue);
            return 0L;
        }

        // 5. 处理科学计数法
        cleanValue = handleScientificNotation(cleanValue);

        // 6. 转换为Long（异常则返回0）
        try {
            BigDecimal bd = new BigDecimal(cleanValue);
            // 非整数也转成整数（比如1999.9→1999，或返回0，根据需求选）
            return bd.longValue(); // 若要严格整数，用longValueExact()，异常时走catch返回0
        } catch (NumberFormatException e) {
            System.err.printf("【转换失败】单元格%s，原始值：%s，清洗后：%s，错误：%s → 转换为0%n",
                    getCellPos(cellData), trimmedValue, cleanValue, e.getMessage());
            return 0L;
        }
    }

    /**
     * 写Excel：Long转字符串
     */
    @Override
    public WriteCellData<?> convertToExcelData(Long value, ExcelContentProperty contentProperty,
                                               GlobalConfiguration globalConfiguration) {
        if (value == null || value == 0L) {
            return new WriteCellData<>("面议"); // 导出时0值显示为"面议"，可根据需求修改
        }
        return new WriteCellData<>(String.valueOf(value));
    }

    // 辅助方法：清洗特殊字符
    private String cleanSpecialChars(String value) {
        String result = value;
        for (String charToClean : CLEAN_CHARS) {
            result = result.replace(charToClean, "");
        }
        return result.trim();
    }

    // 辅助方法：处理科学计数法
    private String handleScientificNotation(String value) {
        if (StringUtils.isBlank(value) || !value.matches("[+-]?\\d+(\\.\\d+)?[eE][+-]?\\d+")) {
            return value;
        }
        return new BigDecimal(value).toPlainString();
    }

    // 辅助方法：获取单元格位置（简化日志）
    private String getCellPos(ReadCellData<?> cellData) {
        if (cellData == null) {
            return "未知位置";
        }
        return cellData.getRowIndex() + "行" + cellData.getColumnIndex() + "列";
    }
}