package com.smppw.modaq.application.components.report.parser.pdf;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.smppw.modaq.application.components.ReportParseUtils;
import com.smppw.modaq.application.components.report.parser.ReportParserConstant;
import com.smppw.modaq.domain.dto.report.*;
import com.smppw.modaq.domain.mapper.EmailFieldMappingMapper;
import org.springframework.stereotype.Component;
import technology.tabula.Table;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Component(ReportParserConstant.PARSER_PDF_LETTER)
public class PDLetterReportParser extends AbstractPDReportParser<LetterReportData> {
    private final Map<String, Object> allInfoMap = MapUtil.newHashMap(32);

    public PDLetterReportParser(EmailFieldMappingMapper fieldMappingMapper) {
        super(fieldMappingMapper);
    }

    @Override
    protected void initTableInfo(List<Table> tables) {
        // 每次重新清空map数据
        this.allInfoMap.clear();
        for (Table table : tables) {
            int rowCount = table.getRowCount();
            int colCount = table.getColCount();
            // 根据特殊行和列处理字段映射关系
            if (rowCount == 2 || colCount > 6) {
                // 表格只有2行或者列数大于6列说明每列是一个字段和值
                if (rowCount == 5) {
                    // 表格有5行说明是申万宏源证券的确认单
                    this.parseHisTable(colCount, table, 2, this.allInfoMap);
                } else {
                    this.parseHisTable(colCount, table, 1, this.allInfoMap);
                }
                continue;
            }
            // 每行的单数列是键，偶数列是值（4列或者2列的表格）
            for (int i = 0; i < rowCount; i++) {
                int t = colCount / 2;
                for (int j = 0; j < t; j++) {
                    String key = ReportParseUtils.cleaningValue(table.getCell(i, j * 2).getText());
                    if (StrUtil.isBlank(key)) {
                        continue;
                    }
                    String value = table.getCell(i, j * 2 + 1).getText();
                    this.allInfoMap.put(key, ReportParseUtils.cleaningValue(value, false));
                }
            }
        }
        // 删除key是null或者长度大于100的对象
        this.allInfoMap.entrySet().removeIf(e -> e.getKey() == null || e.getKey().length() > 100);
    }

    @Override
    protected ReportFundInfoDTO buildFundInfo(ReportParserParams params) {
        ReportFundInfoDTO fundInfo = this.buildDto(params.getFileId(), ReportFundInfoDTO.class, this.allInfoMap);
        if (CollUtil.isNotEmpty(this.textList) && fundInfo.getFundName() == null) {
            String fundName = this.textList.get(0);
            if (fundName.contains("_")) {
                fundInfo.setFundCode(fundName.substring(0, fundName.indexOf("_")));
                fundName = StrUtil.split(fundName, "_").get(1);
                this.allInfoMap.put("基金代码", fundInfo.getFundCode());
            }
            this.allInfoMap.put("基金名称", fundName);
            fundInfo.setFundName(fundName);
        }
        return fundInfo;
    }

    @Override
    protected LetterReportData parseExtInfoAndSetData(ReportBaseInfoDTO reportInfo, ReportFundInfoDTO fundInfo) {
        Integer fileId = reportInfo.getFileId();
        if (this.logger.isInfoEnabled()) {
            this.logger.info("文件{} 解析的内容是：{}", fileId, this.allInfoMap);
        }
        // 投资者信息
        ReportInvestorInfoDTO investorInfo = this.buildDto(fileId, ReportInvestorInfoDTO.class, this.allInfoMap);
        // 交易流水
        ReportFundTransactionDTO fundTransaction = this.buildDto(fileId, ReportFundTransactionDTO.class, this.allInfoMap);
        // 构建结果数据
        LetterReportData reportData = new LetterReportData(reportInfo, fundInfo);
        reportData.setInvestorInfo(investorInfo);
        reportData.setFundTransaction(fundTransaction);
        reportData.setAiParse(false);
        return reportData;
    }


    /**
     * 解析键和值是垂直格式的表格数据
     *
     * @param colCount 表格列数
     * @param table    当前表格
     * @param dataRow  值所在的行数
     * @param infoMap  数据对象
     */
    private void parseHisTable(int colCount, Table table, int dataRow, Map<String, Object> infoMap) {
        for (int i = 0; i < colCount; i++) {
            String key = ReportParseUtils.cleaningValue(table.getCell(0, i).getText());
            if (StrUtil.isBlank(key)) {
                continue;
            }
            String value = ReportParseUtils.cleaningValue(table.getCell(dataRow, i).getText(), false);
            if (Objects.equals("无", value)) {
                value = null;
            }
            if (StrUtil.isNotBlank(value) && value.contains("/")) {
                String[] split = value.split("/");
                String[] keySplit = key.split("/");
                for (int k = 0; k < split.length; k++) {
                    infoMap.put(keySplit[k], split[k]);
                }
            } else {
                infoMap.put(key, value);
            }
            if (dataRow == 2 && !infoMap.containsKey("基金名称")) {
                infoMap.put("基金名称", ReportParseUtils.cleaningValue(table.getCell(1, 0).getText()));
            }
        }
    }
}
