package com.simuwang.manage.service.impl;

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.alibaba.fastjson2.JSON;
import com.simuwang.base.common.conts.UserConstants;
import com.simuwang.base.common.enums.EmailCron;
import com.simuwang.base.common.enums.OpenStatusType;
import com.simuwang.base.common.enums.ResultCode;
import com.simuwang.base.common.support.MybatisPage;
import com.simuwang.base.common.util.*;
import com.simuwang.base.config.DaqProperties;
import com.simuwang.base.mapper.MailboxInfoMapper;
import com.simuwang.base.pojo.dos.MailboxInfoDO;
import com.simuwang.base.pojo.dto.MailboxInfoDTO;
import com.simuwang.base.pojo.dto.QuartzBean;
import com.simuwang.base.pojo.dto.query.EmailPageQuery;
import com.simuwang.base.pojo.vo.MailboxInfoTableVO;
import com.simuwang.base.pojo.vo.MailboxInfoVO;
import com.simuwang.base.pojo.vo.OpenStatusVO;
import com.simuwang.base.pojo.vo.ParseParamVO;
import com.simuwang.daq.service.EmailParseApiService;
import com.simuwang.manage.service.EmailConfigService;
import com.smppw.common.pojo.ResultVo;
import com.smppw.utils.DateUtil;
import jakarta.mail.MessagingException;
import jakarta.mail.Store;
import org.quartz.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * FileName: EmailConfigServiceImpl
 * Author:   chenjianhua
 * Date:     2024/9/9 13:40
 * Description: ${DESCRIPTION}
 */
@Service
public class EmailConfigServiceImpl implements EmailConfigService {
    @Autowired
    private MailboxInfoMapper emailConfigMapper;

    @Autowired
    private Scheduler scheduler;

    @Value("${spring.task.groupName}")
    private String groupName;

    @Autowired
    private EmailParseApiService emailParseApiService;

    @Autowired
    private DaqProperties properties;

    private String JOB_CLASS="com.simuwang.manage.task.ParseSchedulerTask";
    private static final Logger logger = LoggerFactory.getLogger(EmailConfigServiceImpl.class);

    @Override
    public MybatisPage<MailboxInfoTableVO> searchEmailConfigList(EmailPageQuery emailPageQuery) {
        List<MailboxInfoDO> mailboxInfoOS = emailConfigMapper.searchEmailConfigList(emailPageQuery);
        List<MailboxInfoTableVO> mailboxInfoTableVOS = mailboxInfoOS.stream().map(MailboxInfoDO::toTableVo).collect(Collectors.toList());
        long total = emailConfigMapper.countEmailConfig(emailPageQuery);
        return MybatisPage.of(total,mailboxInfoTableVOS);
    }
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void saveEmailConfig(MailboxInfoVO mailboxInfoVO) {
        MailboxInfoDO mailboxInfoDO = toMailboxInfoDO(mailboxInfoVO);
        if(mailboxInfoVO.getId() == null){
            mailboxInfoDO.setCreateTime(new Date());
            mailboxInfoDO.setCron(EmailCron.getEmailCronByText(mailboxInfoVO.getCron()).getCron());
            emailConfigMapper.insert(mailboxInfoDO);
        }else{
            emailConfigMapper.updateById(mailboxInfoDO);
        }
        //添加任务
        addJob(mailboxInfoVO);
    }
    private void addJob(MailboxInfoVO mailboxInfoVO) {
        try{
            QuartzUtils.deleteScheduleJob(scheduler,mailboxInfoVO.getEmail(),groupName);
            MailboxInfoDO infoDO = emailConfigMapper.selectEmailConfigByEmail(mailboxInfoVO.getEmail());
            QuartzBean quartzBean = new QuartzBean();
            quartzBean.setCronExpression(infoDO.getCron());
            quartzBean.setStatus(infoDO.getOpenStatus());
            quartzBean.setGroupName(groupName);
            quartzBean.setJobName(mailboxInfoVO.getEmail());
            quartzBean.setJobClass(JOB_CLASS);
            //请求参数
            MailboxInfoDTO paramDTO = new MailboxInfoDTO();
            paramDTO.setAccount(infoDO.getEmail());
            paramDTO.setPassword(getPassword(infoDO.getPassword()));
            paramDTO.setPort(infoDO.getPort());
            paramDTO.setHost(infoDO.getServer());
            paramDTO.setProtocol(infoDO.getProtocol());
            quartzBean.setJobParam(JSON.toJSONString(paramDTO));
            QuartzUtils.createScheduleJob(scheduler,quartzBean);
        }catch (Exception e){
            logger.error(e.getMessage(),e);
        }
    }

    private String getPassword(String password){
        try{
            String publicKey = this.properties.getSecurityRsa().getPublicKey();
            String privateKey = this.properties.getSecurityRsa().getPrivateKey();
            password = new RSA(privateKey, publicKey).decryptStr(password, KeyType.PrivateKey);
        }catch (Exception e){
            logger.error(e.getMessage(),e);
        }
        return password;
    }

    @Override
    public ResultVo connectTest(MailboxInfoVO mailboxInfoVO) {
        ResultVo vo = new ResultVo(ResultCode.CONNECT_SUCCESS);
        MailboxInfoDTO mailboxInfoDTO = new MailboxInfoDTO();
        mailboxInfoDTO.setAccount(mailboxInfoVO.getEmail());
        mailboxInfoDTO.setPassword(getPassword(mailboxInfoVO.getPassword()));
        mailboxInfoDTO.setPort(mailboxInfoVO.getPort());
        mailboxInfoDTO.setHost(mailboxInfoVO.getServer());
        mailboxInfoDTO.setProtocol(mailboxInfoVO.getProtocol());
        Store store = EmailUtil.getStoreNew(mailboxInfoDTO);
        if(store != null){
            try {
                store.close();
            } catch (MessagingException e) {
                throw new RuntimeException(e);
            }
            vo.setMsg(ResultCode.CONNECT_SUCCESS.getMsg());
            vo.setData(true);
            return vo;
        }
        vo = new ResultVo(ResultCode.CONNECT_ERROR);
        vo.setData(false);
        vo.setMsg(ResultCode.CONNECT_ERROR.getMsg());
        return vo;
    }
    @Override
    public void deleteEmailConfig(Integer id) {
        //删除定时任务
        MailboxInfoDO mailboxInfoDO = emailConfigMapper.searchEmailConfigById(id);
        QuartzUtils.deleteScheduleJob(scheduler,mailboxInfoDO.getEmail(),groupName);
        List<Integer> idList = new ArrayList<>();
        idList.add(id);
        emailConfigMapper.deleteEmailConfigByIds(idList);
    }
    @Override
    public boolean checkEmailUnique(String email) {
        MailboxInfoDO mailboxInfoDO = emailConfigMapper.selectEmailConfigByEmail(email);
        if (StringUtil.isNotNull(mailboxInfoDO))
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }
    @Override
    public MailboxInfoVO searchEmailConfigById(Integer id) {
        MailboxInfoDO mailboxInfoDO = emailConfigMapper.searchEmailConfigById(id);
        MailboxInfoVO mailboxInfoVO = mailboxInfoDO.toVo();
        return mailboxInfoVO;
    }
    @Override
    public void controlEmailConfig(OpenStatusVO openStatusVO) {
        MailboxInfoDO mailboxInfoDO = emailConfigMapper.searchEmailConfigById(openStatusVO.getId());
        mailboxInfoDO.setOpenStatus(openStatusVO.getOpenStatus());
        mailboxInfoDO.setUpdateTime(DateUtils.getNowDate());
        emailConfigMapper.updateById(mailboxInfoDO);
        //设置定时任务
        QuartzUtils.deleteScheduleJob(scheduler,mailboxInfoDO.getEmail(),groupName);
        if(openStatusVO.getOpenStatus().equals(OpenStatusType.YES.getCode())){
            QuartzBean quartzBean = new QuartzBean();
            quartzBean.setCronExpression(mailboxInfoDO.getCron());
            quartzBean.setStatus(mailboxInfoDO.getOpenStatus());
            quartzBean.setGroupName(groupName);
            quartzBean.setJobName(mailboxInfoDO.getEmail());
            quartzBean.setJobClass(JOB_CLASS);
            //请求参数
            MailboxInfoDTO paramDTO = new MailboxInfoDTO();
            paramDTO.setAccount(mailboxInfoDO.getEmail());
            paramDTO.setPassword(mailboxInfoDO.getPassword());
            paramDTO.setPort(mailboxInfoDO.getPort());
            paramDTO.setHost(mailboxInfoDO.getServer());
            paramDTO.setProtocol(mailboxInfoDO.getProtocol());
            quartzBean.setJobParam(JSON.toJSONString(paramDTO));
            QuartzUtils.createScheduleJob(scheduler,quartzBean);
        }
    }
    @Override
    public List<MailboxInfoDO> getAll() {
        return emailConfigMapper.getAll();
    }

    @Override
    public MailboxInfoDO selectEmailConfigByEmail(String email) {
        return emailConfigMapper.selectEmailConfigByEmail(email);
    }

    @Override
    public void runOnce(Integer id) {
        MailboxInfoDO mailboxInfoDO = emailConfigMapper.searchEmailConfigById(id);
        QuartzUtils.runOnce(scheduler,mailboxInfoDO.getEmail(),groupName);
    }

    @Override
    public void parseEmail(ParseParamVO parseParamVO) {
        Integer id = parseParamVO.getId();
        String startDate = parseParamVO.getStartDate();
        String endDate = null;
        if(StringUtil.isEmpty(parseParamVO.getEndDate())){
            endDate = DateUtils.getAroundToday(1);
        }else{
            endDate = DateUtil.getAroundDate(DateUtils.parse(parseParamVO.getEndDate(),DateUtils.YYYY_MM_DD),1);
        }
        MailboxInfoDO mailboxInfoDO = emailConfigMapper.searchEmailConfigById(id);
        MailboxInfoDTO mailboxInfoDTO = new MailboxInfoDTO();
        mailboxInfoDTO.setAccount(mailboxInfoDO.getEmail());
        String password = mailboxInfoDO.getPassword();
        try{
            String publicKey = this.properties.getSecurityRsa().getPublicKey();
            String privateKey = this.properties.getSecurityRsa().getPrivateKey();
            password = new RSA(privateKey, publicKey).decryptStr(password, KeyType.PrivateKey);
        }catch (Exception e){
            logger.error(e.getMessage(),e);
        }
        mailboxInfoDTO.setPassword(password);
        mailboxInfoDTO.setPort(mailboxInfoDO.getPort());
        mailboxInfoDTO.setHost(mailboxInfoDO.getServer());
        mailboxInfoDTO.setProtocol(mailboxInfoDO.getProtocol());
        emailParseApiService.parseEmail(mailboxInfoDTO,DateUtils.parse(startDate,DateUtils.YYYY_MM_DD),DateUtils.parse(endDate,DateUtils.YYYY_MM_DD));

    }

    private MailboxInfoDO toMailboxInfoDO(MailboxInfoVO mailboxInfoVO) {
        MailboxInfoDO mailboxInfoDO = new MailboxInfoDO();
        mailboxInfoDO.setIsvalid(1);
        mailboxInfoDO.setId(mailboxInfoVO.getId());
        mailboxInfoDO.setEmail(mailboxInfoVO.getEmail());
        mailboxInfoDO.setCron(EmailCron.getEmailCronByText(mailboxInfoVO.getCron()).getCron());
        mailboxInfoDO.setServer(mailboxInfoVO.getServer());
        mailboxInfoDO.setPort(mailboxInfoVO.getPort());
        mailboxInfoDO.setDescription(mailboxInfoVO.getDescription());
        mailboxInfoDO.setPassword(mailboxInfoVO.getPassword());
        mailboxInfoDO.setType(mailboxInfoVO.getType());
        mailboxInfoDO.setProtocol(mailboxInfoVO.getProtocol());
        mailboxInfoDO.setOpenStatus(mailboxInfoVO.getOpenStatus());
        mailboxInfoDO.setUpdateTime(new Date());
        mailboxInfoDO.setUpdaterId(999);
        mailboxInfoDO.setCreatorId(999);
        return mailboxInfoDO;
    }


}
