package com.storlead.sales.task.dispatch;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.storlead.framework.common.util.encryptor.AccessKeyEncryptor;
import com.storlead.mail.connection.config.MailProperties;
import com.storlead.mail.pojo.entity.EmailsEntity;
import com.storlead.mail.pojo.entity.SmtpPopSettingsEntity;
import com.storlead.mail.service.EmailsService;
import com.storlead.mail.service.SmtpPopSettingsService;
import com.sun.mail.imap.IMAPFolder;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.mail.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: sp-sales-platform
 * @description:
 * @author: chenkq
 * @create: 2025-03-12 09:47
 */
@Slf4j
@Component
@NoArgsConstructor
@DisallowConcurrentExecution
public class DelayDeleteServerEmailTaskJob implements Job {

    @Resource
    private SmtpPopSettingsService smtpPopSettingsService;

    @Resource
    private EmailsService emailsService;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        List<EmailsEntity> taskEntities =  emailsService.getDelayDeleteMail();
        if (CollectionUtil.isNotEmpty(taskEntities)) {
            Map<Long,List<EmailsEntity>> attachmentsMap = taskEntities.stream().collect(Collectors.groupingBy(EmailsEntity::getSmtpPopId));
            for (Map.Entry<Long, List<EmailsEntity>> entry : attachmentsMap.entrySet()) {
                SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getById(entry.getKey());
                if (Objects.nonNull(smtpPop) && Integer.valueOf(0).equals(smtpPop.getIsDeleteMail())) {
                    continue;
                }
                List<EmailsEntity>  entryls = entry.getValue();
                if (!CollectionUtils.isEmpty(entryls)) {
                    AccessKeyEncryptor accessKeyEncryptor = AccessKeyEncryptor.getAccessKeyEncryptor("");
                    String pass = accessKeyEncryptor.decrypt(smtpPop.getEmailPassword());
                    smtpPop.setEmailPassword(pass);
                    MailProperties properties1 = new MailProperties(smtpPop);
                    Properties properties = new Properties();
                    properties.put("mail.imap.host", properties1.getHost());
                    properties.put("mail.imap.port", properties1.getPort());
                    properties.put("mail.imap.starttls.enable", "true");
                    properties.put("mail.imap.ssl.trust", "*");
                    properties.put("mail.imap.ssl.enable", "true");

                    Authenticator auth = new Authenticator() {
                        protected PasswordAuthentication getPasswordAuthentication() {
                            return new PasswordAuthentication(properties1.getEmailAddress(), properties1.getEmailPassword());
                        }
                    };
                    Session session = Session.getInstance(properties,auth);
                    List<EmailsEntity> inEntryls = entryls.stream().filter(e ->e.getFolder().equals("INBOX")).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(inEntryls)) {
                        expungeMailData(inEntryls,properties1,session,"INBOX");
                    }
                    List<EmailsEntity> outEntryls = entryls.stream().filter(e ->e.getFolder().equals("SENT")).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(outEntryls)) {
                        expungeMailData(outEntryls,properties1,session,"SENT");
                    }
                }
            }
        }
    }

    public void expungeMailData(List<EmailsEntity> entryls,MailProperties properties1,Session session,String folder) {
        try {
            // 连接 IMAP 服务器
            Store store = session.getStore(properties1.getProtocol().toLowerCase());
            store.connect(properties1.getEmailAddress(), properties1.getEmailPassword());
            // 打开 INBOX 目录（可写模式）
            if ("SENT".equals(folder)) {
                folder = "Sent Items";
            }
            IMAPFolder inbox = (IMAPFolder)store.getFolder(folder);
            inbox.open(Folder.READ_WRITE);
            int totalDeleted = 0;
            List<Long> deleteIds = new ArrayList<>();
            List<Long> nullIds = new ArrayList<>();
            // 遍历 Message-ID 进行搜索并彻底删除
            for (EmailsEntity entity : entryls) {
                Message message = inbox.getMessageByUID(Long.parseLong(entity.getMsgUid()));
                if (Objects.nonNull(message)) {
                    message.setFlag(Flags.Flag.DELETED, true);
                    totalDeleted++;
                    log.error(" - 彻底删除邮件: " + message.getSubject());
                    deleteIds.add(entity.getId());
                } else {
                    nullIds.add(entity.getId());
                }
            }
            if (!CollectionUtils.isEmpty(nullIds)) {
                LambdaUpdateWrapper<EmailsEntity> nullUp = new LambdaUpdateWrapper<>();
                nullUp.set(EmailsEntity::getDeleteTag,2);
                nullUp.in(EmailsEntity::getId,nullIds);
                emailsService.update(nullUp);
            }
            // 确保邮件彻底删除
            if (totalDeleted > 0) {
                inbox.expunge();
                if (!CollectionUtils.isEmpty(nullIds)) {
                    LambdaUpdateWrapper<EmailsEntity> deleteUp = new LambdaUpdateWrapper<>();
                    deleteUp.set(EmailsEntity::getDeleteTag,1);
                    deleteUp.in(EmailsEntity::getId,deleteIds);
                    emailsService.update(deleteUp);
                }
                log.error("已彻底删除 " + totalDeleted + " 封邮件！");
            }
            // 关闭连接
            inbox.close(true);
            store.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
