package com.simuwang.daq.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.simuwang.base.common.conts.DateConst;
import com.simuwang.base.common.util.EmailUtil;
import com.simuwang.base.mapper.EmailFileInfoMapper;
import com.simuwang.base.mapper.EmailParseInfoMapper;
import com.simuwang.base.pojo.dos.EmailFileInfoDO;
import com.simuwang.base.pojo.dos.EmailParseInfoDO;
import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
import com.simuwang.base.pojo.dto.EmailFundNavDTO;
import com.simuwang.base.pojo.dto.EmailInfoDTO;
import com.simuwang.base.pojo.dto.MailboxInfoDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author mozuwen
 * @date 2024-09-12
 * @description 邮件解析服务对外接口实现层
 */
@Service
public class EmailParseApiServiceImpl implements EmailParseApiService {

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

    private final EmailParseService emailParseService;
    private final EmailParseInfoMapper emailParseInfoMapper;
    private final EmailFileInfoMapper emailFileInfoMapper;
    private final ThreadPoolTaskExecutor asyncExecutor;

    public EmailParseApiServiceImpl(EmailParseService emailParseService, EmailParseInfoMapper emailParseInfoMapper,
                                    EmailFileInfoMapper emailFileInfoMapper, @Qualifier("asyncExecutor") ThreadPoolTaskExecutor asyncExecutor) {
        this.emailParseService = emailParseService;
        this.emailParseInfoMapper = emailParseInfoMapper;
        this.emailFileInfoMapper = emailFileInfoMapper;
        this.asyncExecutor = asyncExecutor;
    }

    @Override
    public void parseEmail(MailboxInfoDTO mailboxInfoDTO, Date startDate, Date endDate) {
        asyncExecutor.execute(() -> emailParseService.parseEmail(mailboxInfoDTO, startDate, endDate));
    }

    @Override
    public void reparseEmail(Integer emailId) {
        // 查询邮件信息
        EmailParseInfoDO emailParseInfoDO = emailParseInfoMapper.queryById(emailId);
        if (emailParseInfoDO == null) {
            log.info("邮件不存在 ->邮件id:{}", emailId);
            return;
        }
        List<EmailFileInfoDO> emailFileInfoDOList = emailFileInfoMapper.queryByEmailId(emailId);
        if (CollUtil.isEmpty(emailFileInfoDOList)) {
            log.info("该邮件不存在附件 -> 邮件id:{}", emailId);
            return;
        }
        // 邮件字段识别映射表
        Map<String, List<String>> emailFieldMap = emailParseService.getEmailFieldMapping();
        // 邮件类型配置
        Map<Integer, List<String>> emailTypeMap = emailParseService.getEmailType();

        // 解析流程
        List<EmailContentInfoDTO> emailContentInfoDTOList = buildEmailContentInfoDTO(emailId, emailParseInfoDO, emailFileInfoDOList, emailTypeMap);

        List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
        Map<EmailContentInfoDTO, List<EmailFundNavDTO>> fileNameNavMap = MapUtil.newHashMap();
        asyncExecutor.execute(() -> {
            for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) {
                try {
                    List<EmailFundNavDTO> fundNavDTOList = emailParseService.parseEmail(emailContentInfoDTO, emailFieldMap);
                    fileNameNavMap.put(emailContentInfoDTO, fundNavDTOList);
                    emailFundNavDTOList.addAll(fundNavDTOList);
                } catch (Exception e) {
                    log.error("重新解析邮件失败,邮件id:{},堆栈信息:{}", emailId, ExceptionUtil.stacktraceToString(e));
                }
            }
            // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
            emailParseService.saveRelatedTable(emailParseInfoDO.getEmail(), emailContentInfoDTOList, fileNameNavMap);
        });
    }

    @Override
    public void reparseFile(List<Integer> fileIdList) {
        if (CollUtil.isEmpty(fileIdList)) {
            return;
        }
        List<EmailInfoDTO> emailParseInfoDOList = emailParseInfoMapper.queryValuationEmailByFileId(fileIdList);
        if (CollUtil.isEmpty(emailParseInfoDOList)) {
            return;
        }
        asyncExecutor.execute(() -> {
            Map<Integer, List<EmailInfoDTO>> emailIdFileMap = emailParseInfoDOList.stream().collect(Collectors.groupingBy(EmailInfoDTO::getId));
            for (Map.Entry<Integer, List<EmailInfoDTO>> entry : emailIdFileMap.entrySet()) {
                Integer emailId = entry.getKey();
                List<EmailInfoDTO> emailInfoDTOList = entry.getValue();
                String emailAddress = emailInfoDTOList.get(0).getEmail();
                List<EmailContentInfoDTO> emailContentInfoDTOList = emailInfoDTOList.stream().map(this::buildEmailContentInfoDTO).collect(Collectors.toList());

                List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
                Map<EmailContentInfoDTO, List<EmailFundNavDTO>> fileNameNavMap = MapUtil.newHashMap();
                for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) {
                    try {
                        log.info("开始重新解析文件 -> 文件id:{}", emailContentInfoDTO.getFielId());
                        List<EmailFundNavDTO> fundNavDTOList = emailParseService.parseEmail(emailContentInfoDTO, MapUtil.newHashMap());
                        fileNameNavMap.put(emailContentInfoDTO, fundNavDTOList);
                        emailFundNavDTOList.addAll(fundNavDTOList);
                    } catch (Exception e) {
                        log.error("重新解析文件失败,邮件id:{},文件id:{},堆栈信息:{}", emailId, emailContentInfoDTO.getFielId(), ExceptionUtil.stacktraceToString(e));
                    }
                }
                // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
                emailParseService.saveRelatedTable(emailAddress, emailContentInfoDTOList, fileNameNavMap);
            }
            log.info("重新解析文件结束... -> 文件id:{}", fileIdList);
        });
    }

    private EmailContentInfoDTO buildEmailContentInfoDTO(EmailInfoDTO emailInfoDTO) {
        String emailDate = DateUtil.format(emailInfoDTO.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS);
        String parseDate = DateUtil.format(new Date(), DateConst.YYYY_MM_DD_HH_MM_SS);
        EmailContentInfoDTO contentInfoDTO = new EmailContentInfoDTO();
        contentInfoDTO.setEmailId(emailInfoDTO.getId());
        contentInfoDTO.setFielId(emailInfoDTO.getFileId());
        contentInfoDTO.setEmailAddress(emailInfoDTO.getEmail());
        contentInfoDTO.setEmailDate(emailDate);
        contentInfoDTO.setEmailTitle(emailInfoDTO.getEmailTitle());
        contentInfoDTO.setParseDate(parseDate);
        contentInfoDTO.setFileName(emailInfoDTO.getFileName());
        contentInfoDTO.setFilePath(emailInfoDTO.getFilePath());
        contentInfoDTO.setEmailType(emailInfoDTO.getEmailType());
        return contentInfoDTO;
    }

    private List<EmailContentInfoDTO> buildEmailContentInfoDTO(Integer emailId, EmailParseInfoDO emailParseInfoDO, List<EmailFileInfoDO> emailFileInfoDOList, Map<Integer, List<String>> emailTypeMap) {
        List<EmailContentInfoDTO> emailContentInfoDTOList = CollUtil.newArrayList();
        String emailDate = DateUtil.format(emailParseInfoDO.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS);
        String parseDate = DateUtil.format(new Date(), DateConst.YYYY_MM_DD_HH_MM_SS);
        for (EmailFileInfoDO fileInfoDO : emailFileInfoDOList) {
            EmailContentInfoDTO contentInfoDTO = new EmailContentInfoDTO();
            contentInfoDTO.setEmailId(emailId);
            contentInfoDTO.setFielId(fileInfoDO.getId());
            contentInfoDTO.setEmailAddress(emailParseInfoDO.getEmail());
            contentInfoDTO.setEmailDate(emailDate);
            contentInfoDTO.setEmailTitle(emailParseInfoDO.getEmailTitle());
            contentInfoDTO.setParseDate(parseDate);
            contentInfoDTO.setFileName(fileInfoDO.getFileName());
            contentInfoDTO.setFilePath(fileInfoDO.getFilePath());
            Integer emailType = EmailUtil.getEmailTypeBySubject(emailParseInfoDO.getEmailTitle(), emailTypeMap);
            contentInfoDTO.setEmailType(emailType);
            String emailContent = readHtmlFileContent(fileInfoDO.getFilePath());
            contentInfoDTO.setEmailContent(emailContent);
            emailContentInfoDTOList.add(contentInfoDTO);
        }
        return emailContentInfoDTOList;
    }

    public static String readHtmlFileContent(String filePath) {
        if (StrUtil.isNotBlank(filePath) && filePath.endsWith("html")) {
            StringBuilder content = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    // 追加每一行到StringBuilder中
                    content.append(line).append("\n");
                }
            } catch (IOException e) {
                System.err.println("Error reading the file: " + e.getMessage());
                return null;
            }
            return content.toString();
        }
        return null;
    }

}
