package com.simuwang.daq.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.simuwang.base.common.conts.EmailTypeConst;
import com.simuwang.base.common.util.ExcelUtil;
import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
import com.simuwang.base.pojo.dto.EmailFundNavDTO;
import com.simuwang.base.pojo.dto.ValuationPdfTransformToExcelDTO;
import com.simuwang.base.pojo.valuation.AssetsValuationResult;
import com.simuwang.base.pojo.valuation.ParseValuationInfo;
import com.simuwang.base.pojo.valuation.ValuationNeedParseParam;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author mozuwen
 * @date 2024-09-12
 * @description 估值表邮件解析器
 */
@Component
public class ValuationEmailParser extends AbstractEmailParser {

    private final ValuationParseService valuationParseService;
    private final PdfToExcelService pdfToExcelService;

    public ValuationEmailParser(ValuationParseService valuationParseService, PdfToExcelService pdfToExcelService) {
        this.valuationParseService = valuationParseService;
        this.pdfToExcelService = pdfToExcelService;
    }

    @Override
    public boolean isSupport(Integer emailType) {
        return EmailTypeConst.VALUATION_EMAIL_TYPE.equals(emailType);
    }

    @Override
    public List<EmailFundNavDTO> parse(EmailContentInfoDTO emailContentInfoDTO, Map<String, List<String>> emailFieldMap) {
        List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
        boolean isSatisfiedParse = emailContentInfoDTO != null && StrUtil.isNotBlank(emailContentInfoDTO.getFileName())
                && (ExcelUtil.isExcel(emailContentInfoDTO.getFileName()) || ExcelUtil.isPdf(emailContentInfoDTO.getFileName()) || ExcelUtil.isZip(emailContentInfoDTO.getFileName()));
        if (!isSatisfiedParse) {
            return emailFundNavDTOList;
        }
        List<ValuationNeedParseParam> valuationNeedParseParams = buildValuationNeedParseParam(emailContentInfoDTO);
        List<AssetsValuationResult.Record> recordList = valuationParseService.parseValuationExcel(valuationNeedParseParams);
        if (CollUtil.isNotEmpty(recordList)) {
            List<AssetsValuationResult.Record> parseSuccessList = recordList.stream()
                    .filter(e -> e.getSuccess() == 1 || (StrUtil.isNotBlank(e.getMsg()) && "未匹配基金".equals(e.getMsg()))).collect(Collectors.toList());
            List<EmailFundNavDTO> fundNavDTOList = convertToFundNavDTO(parseSuccessList);
            Optional.ofNullable(fundNavDTOList).ifPresent(emailFundNavDTOList::addAll);
        }
        return emailFundNavDTOList;
    }

    private List<ValuationNeedParseParam> buildValuationNeedParseParam(EmailContentInfoDTO emailContentInfoDTO) {
        String fileName = emailContentInfoDTO.getFileName();
        String filePath = emailContentInfoDTO.getFilePath();
        if (StrUtil.isNotBlank(fileName) && ExcelUtil.isZip(fileName)) {
            List<String> filePathList = compressedFile(filePath, fileName);
            if (CollUtil.isEmpty(filePathList)) {
                return CollUtil.newArrayList();
            }
            List<ValuationNeedParseParam> parseParamList = CollUtil.newArrayList();
            for (String path : filePathList) {
                ValuationNeedParseParam parseParam = new ValuationNeedParseParam();
                parseParam.setFile(new File(path));
                parseParam.setFileUrl(path);
                parseParam.setOriginFileName(fileName);
                parseParam.setFundId(null);
                parseParam.setFromEmail(1);
                // pdf格式文件转成excel
                transformPdfToExcel(parseParam);
                parseParamList.add(parseParam);
            }
            return parseParamList;
        } else {
            File file = new File(filePath);
            ValuationNeedParseParam parseParam = new ValuationNeedParseParam();
            parseParam.setFile(file);
            parseParam.setFileUrl(filePath);
            parseParam.setOriginFileName(fileName);
            parseParam.setFundId(null);
            parseParam.setFromEmail(1);
            // pdf格式文件转成excel
            transformPdfToExcel(parseParam);
            return ListUtil.toList(parseParam);
        }
    }

    private List<String> compressedFile(String filePath, String fileName) {
        List<String> filePathList = CollUtil.newArrayList();
        String destPath = filePath.substring(0, filePath.indexOf(fileName)) + fileName.replaceAll(".zip", "").replaceAll(".ZIP", "");
        List<String> compressedFiles = ExcelUtil.extractCompressedFiles(filePath, destPath);
        for (String path : compressedFiles) {
            boolean isSatisfiedParse = ExcelUtil.isExcel(path) || ExcelUtil.isPdf(path) || ExcelUtil.isZip(path);
            if (!isSatisfiedParse) {
                continue;
            }
            if (ExcelUtil.isZip(path)) {
                filePathList.addAll(compressedFile(path, new File(path).getName()));
            }
            File file = new File(path);
            if (file.isDirectory()) {
                filePathList.addAll(Arrays.stream(Objects.requireNonNull(file.list())).toList());
            }
            filePathList.add(path);
        }
        return filePathList;
    }

    private void transformPdfToExcel(ValuationNeedParseParam valuationNeedParseParam) {
        String originFileName = valuationNeedParseParam.getOriginFileName();
        if (StrUtil.isNotBlank(originFileName) && !ExcelUtil.isPdf(originFileName)) {
            return;
        }
        File file = valuationNeedParseParam.getFile();
        valuationNeedParseParam.setFileUrl(file.getAbsolutePath());
        //将pdf文件转为excel
        List<ValuationPdfTransformToExcelDTO> toExcelDTOList = pdfToExcelService.pdfToExcel(ListUtil.toList(file));
        Map<String, ValuationPdfTransformToExcelDTO> pdfToExcelMap = MapUtil.newHashMap();
        if (CollUtil.isNotEmpty(toExcelDTOList)) {
            pdfToExcelMap = toExcelDTOList.stream().collect(Collectors.toMap(ValuationPdfTransformToExcelDTO::getOriginalFileName, v -> v));
        }
        ValuationPdfTransformToExcelDTO toExcelDTO = pdfToExcelMap.get(originFileName);
        valuationNeedParseParam.setFile(toExcelDTO != null ? toExcelDTO.getExcelFile() : null);
    }

    private List<EmailFundNavDTO> convertToFundNavDTO(List<AssetsValuationResult.Record> parseSuccessList) {
        if (CollUtil.isEmpty(parseSuccessList)) {
            return null;
        }
        List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
        // 考虑一个估值表匹配到多个基金的情况
        for (AssetsValuationResult.Record record : parseSuccessList) {
            EmailFundNavDTO fundNavDTO = new EmailFundNavDTO();
            fundNavDTO.setFundName(record.getParseValuationInfo() != null ? record.getParseValuationInfo().getFundName() : null);
            fundNavDTO.setRegisterNumber(record.getParseValuationInfo() != null ? record.getParseValuationInfo().getRegisterNumber() : null);
            fundNavDTO.setPriceDate(record.getDate());
            fundNavDTO.setNav(record.getNav());
            fundNavDTO.setCumulativeNavWithdrawal(record.getCumulativeNavWithdrawal());
            fundNavDTO.setAssetNet(record.getAssetNet());
            fundNavDTO.setAssetShare(record.getAssetShare());
            fundNavDTO.setFundIdList(StrUtil.isNotBlank(record.getFundId()) ? ListUtil.toList(record.getFundId()) : null);
            emailFundNavDTOList.add(fundNavDTO);
        }
        return emailFundNavDTOList;
    }
}
