package com.storlead.sales.controller.mail;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.storlead.framework.common.constant.CommonConstant;
import com.storlead.framework.common.util.RandomGenerateHelper;
import com.storlead.framework.common.util.encryptor.AccessKeyEncryptor;
import com.storlead.framework.util.LoginUserUtil;
import com.storlead.framework.common.result.Result;
import com.storlead.framework.mybatis.entity.SysBaseField;
import com.storlead.mail.controller.EmailServiceChecker;
import com.storlead.mail.pojo.*;
import com.storlead.mail.pojo.entity.*;
import com.storlead.mail.pojo.vo.*;
import com.storlead.mail.service.*;
import com.storlead.mail.util.FileExtractor;
import com.storlead.sales.pojo.entity.customer.CustomerCompanyEntity;
import com.storlead.sales.pojo.entity.customer.CustomerEntity;
import com.storlead.sales.pojo.entity.customer.LiaisonEntity;
import com.storlead.sales.pojo.vo.customer.CustomerListVO;
import com.storlead.sales.pojo.entity.mail.CustomerMailBingMarkEntity;
import com.storlead.sales.service.customer.CustomerCompanyService;
import com.storlead.sales.service.customer.CustomerService;
import com.storlead.sales.service.customer.LiaisonService;
import com.storlead.mail.connection.MailConnection;
import com.storlead.mail.connection.client.MailConnectionUtil;
import com.storlead.mail.connection.config.MailProperties;
import com.storlead.mail.enums.EmailBoxEnum;
import com.storlead.mail.enums.SendStatus;
import com.storlead.mail.properties.MailFileProperties;
import com.storlead.mail.util.FileHelper;
import com.storlead.mail.util.ZipUtility;
import com.storlead.sales.service.CustomerMailBingMarkService;
import com.storlead.user.pojo.entity.UserEntity;
import com.storlead.user.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.log4j.Log4j2;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.*;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: sp-sales-platform
 * @description:
 * @author: chenkq
 * @create: 2024-05-29 16:02
 */
@RestController
@RequestMapping("/mail")
@Api(tags = "邮件: 邮件管理")
@Log4j2
public class MailApiController {

    @Resource
    private EmailsService emailsService;
    @Resource
    private MailFileProperties mailFileProperties;
    @Resource
    private MailAttachmentService mailAttachmentService;
    @Resource
    private SmtpPopSettingsService smtpPopSettingsService;
    @Resource
    private MailServerPortConfigService serverPortConfigService;
    @Resource
    private IUserService userService;
    @Resource
    private CustomerService customerService;
    @Resource
    private LiaisonService liaisonService;
    @Resource
    private MailTempAttachmentService tempAttachmentService;
    @Resource
    private CustomerMailBingMarkService customerMailBingMarkService;
    @Resource
    private UserMailTrackRecordService mailTrackRecordService;
    @Resource
    private CustomerCompanyService customerCompanyService;

    @Resource
    private Environment environment;

    @PostMapping(value = "/page_list")
    @ApiOperation(value = "获取邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> pageList(MailDTO dto) {
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        EmailBoxEnum boxEnum = EmailBoxEnum.getEnumByCode(dto.getBoxCode());
        SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        if (Objects.isNull(smtpPop)) {
            return Result.result("请先配置邮箱");
        }
        Page<EmailsEntity> page = new Page<>(dto.getPageIndex(), dto.getPageSize());
        if (Objects.isNull(dto.getCustomerId())) {
            dto.setOwnerBy(currentUserId);
            dto.setSmtpPopId(smtpPop.getId());
        }
        if (Objects.nonNull(boxEnum)) {
            dto.setFolder(dto.getBoxCode());
        }
        if (Integer.valueOf(1).equals(dto.getIsTrash())) {
            dto.setIsTrash(1);
        } else {
            dto.setIsTrash(0);
        }

        IPage<EmailsEntity> pageList = null;
        if (Objects.isNull(dto.getCustomerType()) && Objects.isNull(dto.getBindCustomer())) {
            pageList = emailsService.pageWithScope(page, dto);
        } else if (Objects.isNull(dto.getCustomerType())) {
            pageList = emailsService.pageWithScope(page, dto);
        } else {
            pageList = emailsService.pageWithScopeAllCus(page, dto);
        }
        if (!CollectionUtils.isEmpty(pageList.getRecords())) {
            List<EmailsEntity> entities = pageList.getRecords();
            List<Long> mailIds = entities.stream().map(EmailsEntity::getId).collect(Collectors.toList());

            List<Long> allCustomerIds = entities.stream()
                    .map(EmailsEntity::getCustomerIds)                // 获取每个 email 对象的 customerIds 字符串
                    .filter(ids -> ids != null && !ids.isEmpty())      // 确保 customerIds 不为空
                    .flatMap(ids -> List.of(ids.split(",")).stream())  // 拆分每个字符串并扁平化为流
                    .map(String::trim)                                // 去除空格
                    .filter(id -> !id.isEmpty())                      // 过滤掉空字符串
                    .map(id -> {
                        try {
                            return Long.parseLong(id);                 // 转换为 Long
                        } catch (NumberFormatException e) {
                            // 如果转换失败，返回一个默认值或者抛出异常
                            return null;                               // 在此返回 null，之后通过 filter 过滤掉
                        }
                    })
                    .filter(id -> id != null)                         // 过滤掉 null 值
                    .collect(Collectors.toList());                    // 收集结果到 List<Long>

            if (!CollectionUtils.isEmpty(allCustomerIds)) {
                List<CustomerEntity> customerEntityList = customerService.listByIds(allCustomerIds);
                if (!CollectionUtils.isEmpty(customerEntityList)) {
                    DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
                    List<CustomerListVO> customerVols = mapperFactory.getMapperFacade().mapAsList(customerEntityList, CustomerListVO.class);
                    SysBaseField.dictFileds(customerVols);
                    SysBaseField.orgFileds(customerVols);
                    Map<Long, CustomerListVO> customerEntityMap = customerVols.stream().collect(Collectors.toMap(CustomerListVO::getId, CustomerListVO -> CustomerListVO));
                    pageList.getRecords().forEach(e -> {
                        if (StrUtil.isNotBlank(e.getCustomerIds())) {
                            List<Long> customerIds = Arrays.stream(e.getCustomerIds().split(",")).map(Long::parseLong)                            // 将每个 ID 从 String 转换为 Long
                                    .collect(Collectors.toList());

                            e.setCustomerls(new ArrayList<>());
                            //  List<CustomerListVO> customerVOs = customerIds.stream().map(customerEntityMap::get).collect(Collectors.toList());
                            for (Long customerId : customerIds) {

                                CustomerListVO customer = customerEntityMap.get(customerId);
                                if (Objects.nonNull(customer)) {
                                    customer.setResourceType(Objects.nonNull(customer.getCustomerForm()) ? customer.getCustomerForm().toString() : null);
                                    if (currentUserId.equals(customer.getOwnerBy())) {
                                        customer.setIsMyCustomer(1);
                                    } else {
                                        customer.setIsMyCustomer(0);
                                    }
                                    e.getCustomerls().add(customer);
                                    if (Objects.isNull(e.getCustomerVO())) {
                                        e.setCustomerVO(customer);
                                    }
                                }
                            }
                        }
                        e.setFolderName(EmailBoxEnum.getEnumNameByCode(e.getFolder()));
                    });
                }
            }
            if (!CollectionUtils.isEmpty(mailIds)) {

                QueryWrapper countAttachmentGroupWp = new QueryWrapper<>();
                countAttachmentGroupWp.in("email_id",mailIds);
                countAttachmentGroupWp.select("email_id as mailId, COUNT(*) as fileNum").groupBy("email_id");
                List<Map<Long, Object>> countMaps = new ArrayList<>();
                if ("DRAFT".equals(dto.getBoxCode()) || "SENTING".equals(dto.getBoxCode())) {
                    countMaps = tempAttachmentService.listMaps(countAttachmentGroupWp);
                } else {
                    countMaps = mailAttachmentService.listMaps(countAttachmentGroupWp);
                }
                Map<Long, Integer> fileNumMap = new HashMap<>();
                for (Map<Long, Object> map : countMaps) {
                    fileNumMap.put(Long.valueOf(map.get("mailId").toString()), Integer.valueOf(map.get("fileNum").toString()));
                }
                pageList.getRecords().forEach(e -> {
                    if (Objects.isNull(fileNumMap.get(e.getId()))) {
                        e.setAttachmentNum(0);
                    } else {
                        e.setAttachmentNum(fileNumMap.get(e.getId()));
                    }
                });
            }

            if (!CollectionUtils.isEmpty(pageList.getRecords())) {
                pageList.getRecords().forEach(m -> {
                    String folderName = "INBOX".equals(m.getFolder()) ? "收件箱" : "发件箱";
                    m.setFolderName(folderName);
                    m.setFollowStatus(Objects.isNull(m.getFollowUpId()) ? 0 : 1);
                    m.setEmailSizeName(FileHelper.formatFileSize(m.getEmailSize()));
                    if (StrUtil.isBlank(m.getSubject())) {
                        m.setSubject("无主题");
                    }
                });
            }
        }
        return Result.result(pageList);
    }



    @PostMapping(value = "/get_no_read_count")
    @ApiOperation(value = "获取未读邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> getNoReadCount() {

        Long currentUserId = LoginUserUtil.getCurrentUserId();
        SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        if (Objects.nonNull(smtpPop)) {
            return Result.result(0);
        }

        LambdaQueryWrapper<EmailsEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
        queryWrapper.eq(EmailsEntity::getSmtpPopId, smtpPop.getId());
        queryWrapper.ne(EmailsEntity::getFrom, "system@storlead.com");
        queryWrapper.eq(EmailsEntity::getIsRead, Integer.valueOf(0));
        queryWrapper.eq(EmailsEntity::getIsDelete, Integer.valueOf(0));
        queryWrapper.eq(EmailsEntity::getFolder, EmailBoxEnum.INBOX.code);
        Integer c = emailsService.count(queryWrapper);
        return Result.result(c);
    }


    @PostMapping(value = "/send_mail")
    @ApiOperation(value = "发送邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> sendMail(SendMailDTO dto) {

        Long currentUserId = LoginUserUtil.getCurrentUserId();
        SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        AccessKeyEncryptor accessKeyEncryptor = AccessKeyEncryptor.getAccessKeyEncryptor("");
        String pass = accessKeyEncryptor.decrypt(smtpPop.getEmailPassword());
        smtpPop.setEmailPassword(pass);
        if (Objects.isNull(currentUserId) && Objects.nonNull(smtpPop)) {
            return Result.result(null);
        }
        SendStatus result = emailsService.sendEmail(dto, smtpPop);
        if (result.code == SendStatus.SUCCESS.code || result.code == SendStatus.PARTIAL_SUCCESS.code) {
            return Result.ok();
        } else {
            return Result.error(result.getDesc());
        }
    }

    @PostMapping(value = "/asyn_send_mail")
    @ApiOperation(value = "发送邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> asynSendMail(SendMailDTO dto) {

        Long currentUserId = LoginUserUtil.getCurrentUserId();
        SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        AccessKeyEncryptor accessKeyEncryptor = AccessKeyEncryptor.getAccessKeyEncryptor("");
        String pass = accessKeyEncryptor.decrypt(smtpPop.getEmailPassword());
        smtpPop.setEmailPassword(pass);
        if (Objects.isNull(currentUserId) && Objects.nonNull(smtpPop)) {
            return Result.result(null);
        }
        emailsService.sendEmail(dto, smtpPop);
        return Result.ok();
    }

    @PostMapping(value = "/save_draft")
    @ApiOperation(value = "保存草稿")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> saveDraft(SendMailDTO dto) {
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        if (Objects.isNull(currentUserId) || Objects.isNull(smtpPop)) {
            return Result.error("请先设置邮箱账号！");
        }
        EmailsEntity entity = new EmailsEntity();
        if (!CollectionUtils.isEmpty(dto.getRecipientls())) {
            entity.setRecipient(org.apache.commons.lang3.StringUtils.join(dto.getRecipientls(), ","));
        }
        if (!CollectionUtils.isEmpty(dto.getRecipientCcls())) {
            entity.setRecipientCc(org.apache.commons.lang3.StringUtils.join(dto.getRecipientCcls(), ","));
        }
        if (!CollectionUtils.isEmpty(dto.getRecipientBccls())) {
            entity.setRecipientBcc(org.apache.commons.lang3.StringUtils.join(dto.getRecipientBccls(), ","));
        }
        if (Objects.nonNull(dto.getId())) {
            entity.setId(dto.getId());
        }

        entity.setSubject(dto.getSubject());
        entity.setContent(dto.getContent());
        entity.setReplyMsgId(dto.getReplyMsgId());
        entity.setOwnerBy(currentUserId);
        entity.setSmtpPopId(smtpPop.getId());
        entity.setFolder(EmailBoxEnum.DRAFT.code);
        entity.setEmailSize(Long.valueOf(entity.getContent().length()));

        emailsService.saveOrUpdate(entity);
        if (!CollectionUtils.isEmpty(dto.getFileIds())) {
            LambdaUpdateWrapper<MailTempAttachmentEntity> fileWrapper = new LambdaUpdateWrapper<>();
            fileWrapper.set(MailTempAttachmentEntity::getEmailId, entity.getId());
            fileWrapper.in(MailTempAttachmentEntity::getId, dto.getFileIds());
            tempAttachmentService.update(fileWrapper);
        }
        if (!CollectionUtils.isEmpty(dto.getOldfileIds())) {
            LambdaUpdateWrapper<MailAttachmentEntity> fileWrapper = new LambdaUpdateWrapper<>();
            fileWrapper.in(MailAttachmentEntity::getId, dto.getOldfileIds());
            List<MailAttachmentEntity> mailAttachments = mailAttachmentService.list(fileWrapper);
            if (!CollectionUtils.isEmpty(mailAttachments)) {
                List<MailTempAttachmentEntity> files = new ArrayList<>();
                for(MailAttachmentEntity attachment : mailAttachments) {
                    MailTempAttachmentEntity tempAttachment = new MailTempAttachmentEntity();
                    BeanUtils.copyProperties(attachment,tempAttachment);
                    tempAttachment.setId(entity.getId());
                    tempAttachment.setOwnerBy(entity.getOwnerBy());
                    files.add(tempAttachment);
                }
                if (!CollectionUtils.isEmpty(files)) {
                    tempAttachmentService.saveBatch(files);
                }
            }
        }
        return Result.ok();
    }

    @PostMapping(value = "/receive_mail")
    @ApiOperation(value = "接收邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> receiveMail() {
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        if (Objects.isNull(currentUserId) || Objects.isNull(smtpPop)) {
            return Result.error("请先设置邮箱账号！");
        }
        AccessKeyEncryptor accessKeyEncryptor = AccessKeyEncryptor.getAccessKeyEncryptor("");
        String pass = accessKeyEncryptor.decrypt(smtpPop.getEmailPassword());
        smtpPop.setEmailPassword(pass);
        emailsService.receiveEmails(smtpPop);
        return Result.ok();
    }

    @PostMapping(value = "/download_mail_eml_zip")
    @ApiOperation(value = "下载邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public void downloadMailEmlZip(MailDTO dto, HttpServletResponse response) throws MessagingException {
        Long currentUserId = LoginUserUtil.getCurrentUserId();

        if (CollectionUtils.isEmpty(dto.getMailIds())) {
            return;
        }
        List<EmailsEntity> entities = emailsService.list(new LambdaQueryWrapper<EmailsEntity>().in(EmailsEntity::getId, dto.getMailIds()));
        if (CollectionUtils.isEmpty(entities)) {
            return;
        }
        String zipFilePath = mailFileProperties.getPath().getPath() + "temp_eml_files";
        File tempDir = new File(zipFilePath + File.separator + "temp");
//        if (tempDir.exists()) {
//
//        }
        if (!tempDir.exists()) {
            tempDir.mkdirs();
        }

        List<Message> messages = new ArrayList<>();

        entities.forEach(e -> {
            Message message = mailVoToMessages(e);
            if (Objects.nonNull(message)) {
                messages.add(message);
            }
        });
        for (int i = 0; i < messages.size(); i++) {
            Message message = messages.get(i);
            String subject = StrUtil.isNotBlank(message.getSubject()) ? message.getSubject() : "未命名";
            ZipUtility.saveEmlFile(messages.get(i), tempDir.getPath() + "/" + subject + (i + 1) + ".eml");
        }
        File downloadFile = new File(tempDir.getPath());
        if (!downloadFile.exists()) {
            downloadFile.mkdirs();
        }
        File zipFile = new File(zipFilePath + File.separator + "emails" + currentUserId + ".zip");
        try {
            ZipUtility.zipFiles(tempDir, zipFile);
        } catch (IOException e) {
            return;
        }
        try {
            FileInputStream inStream = new FileInputStream(zipFile);
            // 设置响应头
            response.setContentType("application/zip");
            response.setContentLength((int) zipFile.length());
            response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFile.getName() + "\"");
            // 获取输出流
            OutputStream outStream = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;

            // 写入响应输出流
            while ((bytesRead = inStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            log.error("Error occurred while downloading the file: ", e);
        } finally {
            ZipUtility.deleteDirectory(tempDir);
        }
    }


    @PostMapping(value = "/download_mail_eml")
    @ApiOperation(value = "下载邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public void downloadMail(MailDTO dto, HttpServletResponse response) throws MessagingException {
        if (Objects.isNull(dto.getMailId())) {
            return;
        }
        EmailsEntity entitie = emailsService.getById(dto.getMailId());
        if (Objects.isNull(entitie)) {
            return;
        }
        String zipFilePath = mailFileProperties.getPath().getPath() + "temp_eml_files";
        File tempDir = new File(zipFilePath + File.separator + "temp");
        if (!tempDir.exists()) {
            tempDir.mkdirs();
        }

        Message message = mailVoToMessages(entitie);
        String subject = StrUtil.isNotBlank(message.getSubject()) ? message.getSubject() : "未命名";
        String tempPath = tempDir.getPath() + "/" + subject + ".eml";
        ZipUtility.saveEmlFile(message, tempPath);

        File downloadFile = new File(tempPath);
        if (!downloadFile.exists()) {
            downloadFile.mkdirs();
        }
        try {
            FileInputStream inStream = new FileInputStream(downloadFile);
            // 设置响应头
            response.reset();
            response.setContentType("application/octet-stream;charset=utf-8");
            /*
             * 跨域配置
             * */
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
//        String filename = "测试.docx";
            String filename = downloadFile.getName();
            response.addHeader("content-disposition",
                    "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")
                            + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8"));
//		response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            byte[] b = new byte[1024];
            int len;
//从输入流中读取一定数量的字节，并将其存储在缓冲区字节数组中，读到末尾返回-1
            ServletOutputStream outputStream = response.getOutputStream();
            while ((len = inStream.read(b)) > 0) {
                outputStream.write(b, 0, len);
            }
            inStream.close();
            outputStream.close();
        } catch (Exception e) {
            log.error("Error occurred while downloading the file: ", e);
        } finally {
            ZipUtility.deleteDirectory(tempDir);
        }
    }

    public Message mailVoToMessages(EmailsEntity emails) {
        try {
            List<String> recipientls = new ArrayList<>();
            if (StrUtil.isNotBlank(emails.getRecipient())) {
                recipientls = Arrays.asList(emails.getRecipient().split(","));
            }

            List<String> recipientCcls = new ArrayList<>();
            if (StrUtil.isNotBlank(emails.getRecipientCc())) {
                recipientCcls = Arrays.asList(emails.getRecipientCc().split(","));
            }
            List<String> recipientBccls = new ArrayList<>();
            if (StrUtil.isNotBlank(emails.getRecipientBcc())) {
                recipientBccls = Arrays.asList(emails.getRecipientBcc().split(","));
            }

            String fromAddress = emails.getFrom();

            InternetAddress[] froms = new InternetAddress[recipientls.size()];
            for (int i = 0; i < recipientls.size(); i++) {
                froms[i] = new InternetAddress(recipientls.get(i));
            }
            InternetAddress[] fromsCC = new InternetAddress[recipientCcls.size()];
            for (int i = 0; i < recipientCcls.size(); i++) {
                fromsCC[i] = new InternetAddress(recipientCcls.get(i));
            }
            InternetAddress[] fromsBCC = new InternetAddress[recipientBccls.size()];
            for (int i = 0; i < recipientBccls.size(); i++) {
                fromsBCC[i] = new InternetAddress(recipientBccls.get(i));
            }

            Message message = new MimeMessage(Session.getDefaultInstance(new Properties()));
            if (Objects.nonNull(froms) && froms.length > 0) {
                message.setRecipients(Message.RecipientType.TO, froms);
            }
            if (Objects.nonNull(fromsCC) && fromsCC.length > 0) {
                message.setRecipients(Message.RecipientType.CC, fromsCC);
            }
            if (Objects.nonNull(fromsBCC) && fromsBCC.length > 0) {
                message.setRecipients(Message.RecipientType.BCC, fromsBCC);
            }

            LambdaQueryWrapper fileWrapper = new LambdaQueryWrapper<MailTempAttachmentEntity>().in(MailTempAttachmentEntity::getEmailId, emails.getId());
            List<MailTempAttachmentEntity> tempAttachment = tempAttachmentService.list(fileWrapper);
            if (CollectionUtils.isEmpty(tempAttachment)) {
                message.setFrom(new InternetAddress(fromAddress));
                message.setSubject(emails.getSubject());
                message.setContent(emails.getContent(), "text/html; charset=UTF-8");
            } else {
                message.setFrom(new InternetAddress(fromAddress));
                message.setDescription(emails.getRemark());
                // 设置邮件主题
                message.setSubject(emails.getSubject());
                // 创建消息部分
                Multipart multipart = new MimeMultipart();
//                    // 消息正文
                BodyPart messageBodyPart1 = new MimeBodyPart();
                messageBodyPart1.setContent(emails.getContent(), "text/html; charset=UTF-8");
                multipart.addBodyPart(messageBodyPart1);
//                    message.add(dto.getContent(), "UTF-8","text/html");
                // 创建一个多部分消息

                // 设置文本消息部分
                for (MailTempAttachmentEntity attachment : tempAttachment) {
                    BodyPart messageBodyPart = new MimeBodyPart();
                    String filePath = mailFileProperties.getPath().getPath() + attachment.getFilePath();
                    messageBodyPart = new MimeBodyPart();
                    String fileName = attachment.getFileName() + "." + attachment.getFileExt();
                    DataSource fileSource = new FileDataSource(filePath);
                    messageBodyPart.setDataHandler(new DataHandler(fileSource));
                    messageBodyPart.setFileName(fileName);
                    multipart.addBodyPart(messageBodyPart);
                }
                // 发送完整的消息部分
                message.setContent(multipart);
                // 获取邮件大小
            }
            return message;
        } catch (Exception e) {
            return null;
        }
    }

    @PostMapping(value = "/getMailDetail")
    @ApiOperation(value = "获取邮件详情")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> getMailDetail(Long mailId, Long customerId) {
        try {
            if (Objects.isNull(mailId)) {
                return Result.error("参数错误");
            }
            EmailsEntity mail = emailsService.getById(mailId);
            if (Objects.isNull(mail)) {
                return Result.error("邮件不存在");
            }
            LambdaUpdateWrapper<EmailsEntity> update1 = new LambdaUpdateWrapper<>();
            update1.set(EmailsEntity::getIsRead, 1);
            update1.eq(EmailsEntity::getId, mailId);
            emailsService.update(update1);

            Long currentUserId = LoginUserUtil.getCurrentUserId();
            if (Integer.valueOf(1).equals(mail.getIsOnlyHead()) || StrUtil.isBlank(mail.getContent())) {
                SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getById(mail.getSmtpPopId());
                MailProperties properties = new MailProperties(smtpPop);
                MailConnection mailConnection = MailConnectionUtil.receiveEmailsConnection(properties);
                if (Objects.isNull(mailConnection)) {
                    return Result.error("获取邮件失败，请确认邮箱账号密码是否正确");
                }
                String folderName = "INBOX".equals(mail.getFolder()) ? "INBOX" : "Sent Items";
                Message message = mailConnection.getMessageByUid(mail.getMsgUid(), folderName);
                if (Objects.isNull(message)) {
                    return Result.error("获取邮件失败，请确认邮箱账号密码是否正确");
                }
                String bodyContent = emailsService.getEmailBodyContent(message);
                LambdaUpdateWrapper<EmailsEntity> update = new LambdaUpdateWrapper<>();
                update.set(EmailsEntity::getContent, bodyContent);
                update.set(EmailsEntity::getIsOnlyHead, 0);
                update.eq(EmailsEntity::getId, mailId);
                Integer f = mailAttachmentService.count(new LambdaQueryWrapper<MailAttachmentEntity>().eq(MailAttachmentEntity::getEmailId, mailId));
                if (f == 0) {
                    emailsService.downloadMailAttachment(mail.getId(), mail.getRecipientDate(), message.getContent(), smtpPop);
                }
                mail.setContent(bodyContent);
            }
            if (Objects.nonNull(mail) && (EmailBoxEnum.DRAFT.code.equals(mail.getFolder()) || EmailBoxEnum.SENTING.code.equals(mail.getFolder()))) {
                List<MailTempAttachmentEntity> atts = tempAttachmentService.list(new LambdaQueryWrapper<MailTempAttachmentEntity>().eq(MailTempAttachmentEntity::getEmailId, mailId));
                if (!CollectionUtils.isEmpty(atts)) {
                    atts.forEach(e -> {
                        e.setFileSizeName(FileHelper.formatFileSize(e.getFileSize()));
                    });
                }
                mail.setAttachments(atts);
            } else {
                List<MailAttachmentEntity> atts = mailAttachmentService.list(new LambdaQueryWrapper<MailAttachmentEntity>().eq(MailAttachmentEntity::getEmailId, mailId));
                if (!CollectionUtils.isEmpty(atts)) {
                    atts.forEach(e -> {
                        e.setFileSizeName(FileHelper.formatFileSize(e.getFileSize()));
                    });
                }
                mail.setAttachments(atts);
            }
            if (Objects.nonNull(customerId)) {
                mail.setCustomerIds(String.valueOf(customerId));
                // 处理邮箱(只暂当前联系人的邮箱)
                Set<String> validMails = customerService.findEmailByCustomerId(customerId);
                if (CollectionUtils.isEmpty(validMails)) {
                    List<String> emailIds = Arrays.asList(mail.getRecipient().split(","));
                    List<String> filteredIds = emailIds.stream()
                            .filter(validMails::contains)
                            .collect(Collectors.toList());
                    mail.setRecipientCc(String.join(",", filteredIds));

                    if (StrUtil.isNotBlank(mail.getRecipientCc())) {
                        List<String> ccEmailIds = Arrays.asList(mail.getRecipientCc().split(","));
                        List<String> filteredCcEmailIds = ccEmailIds.stream()
                                .filter(validMails::contains)
                                .collect(Collectors.toList());
                        mail.setRecipientCc(String.join(",", filteredCcEmailIds));
                    }
                }
            }
            List<Long> customerIds = customerMailBingMarkService.selectCustomerIdsByMailId(mail.getId());
//        Long customerIds = cusIds;
            List<String> stringCustomerIds = new ArrayList<>();
            if (!CollectionUtils.isEmpty(customerIds)) {
//            stringCustomerIds = Arrays.asList(customerIds.split(","));
//            List<Long> longCustomerIds = stringCustomerIds.stream()
//                    .map(Long::parseLong)            // 将 String 转换为 Long
//                    .collect(Collectors.toList());
                // 收集结果到 List<Long>
                List<CustomerEntity> customerEntityList = customerService.listByIds(customerIds);

                if (!CollectionUtils.isEmpty(customerEntityList)) {
                    DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
                    List<CustomerListVO> customerVols = mapperFactory.getMapperFacade().mapAsList(customerEntityList, CustomerListVO.class);
                    SysBaseField.dictFileds(customerVols);
                    SysBaseField.orgFileds(customerVols);
                    Map<Long, CustomerListVO> customerEntityMap = customerVols.stream().collect(Collectors.toMap(CustomerListVO::getId, CustomerListVO -> CustomerListVO));
                    mail.setCustomerls(new ArrayList<>());
                    for (Long customerIdA : customerIds) {
                        CustomerListVO customer = customerEntityMap.get(customerIdA);
                        if (Objects.nonNull(customer)) {
                            customer.setResourceType(Objects.nonNull(customer.getCustomerForm()) ? customer.getCustomerForm().toString() : null);
                            if (currentUserId.equals(customer.getOwnerBy())) {
                                customer.setIsMyCustomer(1);
                            } else {
                                customer.setIsMyCustomer(0);
                            }
                            mail.getCustomerls().add(customer);
                        }
                    }
                }
            }
            mail.setEmailSizeName(FileHelper.formatFileSize(mail.getEmailSize()));
            if (!ObjectUtils.isEmpty(customerId)) {
                LambdaQueryWrapper<CustomerMailBingMarkEntity> customerFollowUpEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
                customerFollowUpEntityLambdaQueryWrapper.eq(CustomerMailBingMarkEntity::getMailId, mailId);
                customerFollowUpEntityLambdaQueryWrapper.eq(CustomerMailBingMarkEntity::getCustomerId, customerId);
                customerFollowUpEntityLambdaQueryWrapper.eq(CustomerMailBingMarkEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
                customerFollowUpEntityLambdaQueryWrapper.last("limit 1");
                CustomerMailBingMarkEntity customerMailBingMark = customerMailBingMarkService.getOne(customerFollowUpEntityLambdaQueryWrapper);
                if (Objects.nonNull(customerMailBingMark)) {
                    mail.setFollowUpId(customerMailBingMark.getFollowUpId());
                } else {
                    mail.setFollowUpId(null);
                }
            } else if (stringCustomerIds.size() > 1) {
                mail.setFollowUpId(null);
            }
            return Result.result(mail);
        } catch (Exception e) {
            return Result.error("获取邮件失败，请确认邮箱邮件是否已删除");
        }
    }


    @PostMapping(value = "/mv_mail_box")
    @ApiOperation(value = "移动邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> mvMailBox(MailMoveDTO dto) {
        if (Objects.isNull(dto.getEmailId()) || Objects.isNull(dto.getBoxCode())) {
            return Result.error("参数错误！");
        }
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        EmailBoxEnum boxEnum = EmailBoxEnum.getEnumByCode(dto.getBoxCode());
        if (Objects.isNull(boxEnum)) {
            return Result.error("参数错误！");
        }
        EmailsEntity entity = emailsService.getById(dto.getEmailId());
        if (Objects.nonNull(entity) && entity.getOwnerBy().equals(currentUserId)) {
            entity.setFolder(boxEnum.code);
            entity.setUpdateBy(currentUserId);
            emailsService.updateById(entity);
            return Result.ok();
        } else {
            return Result.error("参数错误！");
        }
    }


    @PostMapping(value = "/get_contact_mail")
    @ApiOperation(value = "获取同事邮箱")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = Result.class)
    })
    public Result<?> contactMailAccount() {
        LambdaQueryWrapper<SmtpPopSettingsEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(SmtpPopSettingsEntity::getIsDelete, Integer.valueOf(0));
        List<SmtpPopSettingsEntity> popSettings = smtpPopSettingsService.list(queryWrapper);
        List<Long> userIds = popSettings.stream().map(SmtpPopSettingsEntity::getOwnerBy).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(userIds)) {
            return Result.result(null);

        }
        List<UserEntity> users = userService.list(new LambdaQueryWrapper<UserEntity>().in(UserEntity::getId, userIds));
        if (CollectionUtils.isEmpty(users)) {
            return Result.result(null);
        }
        List<UserMailAccountVO> mailAccountls = new ArrayList<>();

        Map<Long, List<String>> mailAccountsMap = popSettings.stream()
                .collect(Collectors.groupingBy(
                        SmtpPopSettingsEntity::getOwnerBy,
                        Collectors.mapping(SmtpPopSettingsEntity::getEmailAddress, Collectors.toList())
                ));
        users.forEach(u -> {
            UserMailAccountVO vo = new UserMailAccountVO();
            vo.setUserId(u.getId());
            vo.setUserName(u.getRealName());
            List<String> mailAccounts = mailAccountsMap.get(u.getId());
            vo.setMailAccounts(mailAccounts);
            mailAccountls.add(vo);
        });
        return Result.result(mailAccountls);
    }

    @PostMapping(value = "/get_customer_liaison")
    @ApiOperation(value = "获取客户联系人")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = Result.class)
    })
    public Result<?> customerLiaison() {

        LambdaQueryWrapper<CustomerEntity> customerWrapper = new LambdaQueryWrapper();
        customerWrapper.isNotNull(CustomerEntity::getCustomerName);
        customerWrapper.eq(CustomerEntity::getIsDelete, Integer.valueOf(0));
        List<CustomerEntity> customers = customerService.listWithScope(customerWrapper);
        if (CollectionUtils.isEmpty(customers)) {
            return Result.result(null);
        }
        List<Long> customerIds = customers.stream().map(CustomerEntity::getId).collect(Collectors.toList());

        LambdaQueryWrapper<LiaisonEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.isNotNull(LiaisonEntity::getName);
        queryWrapper.isNotNull(LiaisonEntity::getEmail);
        queryWrapper.in(LiaisonEntity::getCustomerId, customerIds);
        queryWrapper.eq(LiaisonEntity::getIsDelete, Integer.valueOf(0));
        List<LiaisonEntity> liaisonls = liaisonService.listWithScope(queryWrapper);

        if (CollectionUtils.isEmpty(liaisonls)) {
            return Result.result(null);
        }

        List<CustomerLiaisonMailVO> customerLiaisonls = new ArrayList<>();
        Map<Long, CustomerEntity> customerMap = customers.stream().collect(Collectors.toMap(CustomerEntity::getId, a -> a));
        liaisonls.forEach(u -> {
            CustomerLiaisonMailVO vo = new CustomerLiaisonMailVO();
            vo.setEmail(u.getEmail());
            vo.setLiaisonName(u.getName());
            vo.setCustomerId(u.getCustomerId());
            CustomerEntity customer = customerMap.get(u.getCustomerId());
            if (Objects.nonNull(customer)) {
                vo.setCustomerName(customer.getCustomerName());
                vo.setCountry(customer.getCountry());
                customerLiaisonls.add(vo);
            }
        });
        return Result.result(customerLiaisonls);
    }

    @PostMapping(value = "/get_mail_customer_liaison")
    @ApiOperation(value = "获取客户联系人" )
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = Result.class)
    })
    public Result<?> getMailCustomerLiaison(@RequestBody QueryEmailAddressDTO dto) {

//        LambdaQueryWrapper<CustomerEntity> customerWrapper = new LambdaQueryWrapper();
//        customerWrapper.isNotNull(CustomerEntity::getCustomerName);
//        customerWrapper.eq(CustomerEntity::getIsDelete,Integer.valueOf(0));
//        List<CustomerEntity> customers = customerService.listWithScope(customerWrapper);
//        if (CollectionUtils.isEmpty(customers)) {
//            return Result.result(null);
//        }
//        List<Long> customerIds = customers.stream().map(CustomerEntity::getId).collect(Collectors.toList());
        IPage<LiaisonEntity> page = new Page<>(dto.getPageIndex(),dto.getPageSize());
//        queryWrapper.isNotNull(LiaisonEntity::getName);
//        queryWrapper.isNotNull(LiaisonEntity::getEmail);
//        if (StrUtil.isNotBlank(dto.getBlurry())) {
//            queryWrapper.like(LiaisonEntity::getEmail,dto.getBlurry());
//        }
//        if (!CollectionUtils.isEmpty(customerIds)) {
//            queryWrapper.in(LiaisonEntity::getCustomerId, customerIds);
//        }
//        queryWrapper.isNotNull(LiaisonEntity::getCustomerId);
//        queryWrapper.eq(LiaisonEntity::getIsDelete,Integer.valueOf(0));
//        IPage<LiaisonEntity> liaisonPage = liaisonService.pageWithScope(page,queryWrapper,dto);
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        IPage<CustomerLiaisonMailVO> rpage = new Page<>(dto.getPageIndex(),dto.getPageSize());
        LambdaQueryWrapper<LiaisonEntity> wrapper = new LambdaQueryWrapper();
        wrapper.isNotNull(LiaisonEntity::getEmail)
                .ne(LiaisonEntity::getEmail, "");
        wrapper.apply(" (FIND_IN_SET("+currentUserId+", collaborator) or owner_by = "+currentUserId+") ");
        if (StrUtil.isNotBlank(dto.getBlurry())) {
            wrapper.apply(" (country like '%"+dto.getBlurry()+"%' or customerName like '%"+dto.getBlurry()+"%' or email like '%"+dto.getBlurry()+"%' or `name` like '%"+dto.getBlurry()+"%')");
//            wrapper.and(w ->w.like(LiaisonEntity::getCustomerName,dto.getBlurry()).or().like(LiaisonEntity::getLiaisonName,dto.getBlurry()).or().like(LiaisonEntity::getEmail,dto.getBlurry()));
        }

         List<LiaisonEntity> liaisonls = liaisonService.listWith(page,wrapper);
        if (CollectionUtils.isEmpty(liaisonls)) {
            return Result.result(page);
        }

//        List<Long> customerIds = liaisonls.stream().map(LiaisonEntity::getCustomerId).collect(Collectors.toList());
        List<CustomerLiaisonMailVO> customerLiaisonls = new ArrayList<>();
//        LambdaQueryWrapper<CustomerEntity> customerWrapper = new LambdaQueryWrapper();
//        customerWrapper.in(CustomerEntity::getId, customerIds);
//        customerWrapper.eq(CustomerEntity::getIsDelete,Integer.valueOf(0));
//        List<CustomerEntity> customers = customerService.listWithScope(customerWrapper);

//        Map<Long,CustomerEntity> customerMap =  customers.stream().collect(Collectors.toMap(CustomerEntity::getId,a ->a));
        liaisonls.forEach(u ->{
            CustomerLiaisonMailVO vo = new CustomerLiaisonMailVO();
            vo.setEmail(u.getEmail());
            vo.setEmail1(u.getEmail1());
            vo.setEmail2(u.getEmail2());
            vo.setEmail3(u.getEmail3());
            vo.setLiaisonName(u.getName());
            vo.setCustomerId(u.getCustomerId());
            vo.setCustomerName(u.getCustomerName());
            vo.setCountry(u.getCountry());
//            CustomerEntity customer = customerMap.get(u.getCustomerId());
//            if (Objects.nonNull(customer)) {
//                vo.setCustomerName(customer.getCustomerName());
//                vo.setCountry(customer.getCountry());
//
//            }
            customerLiaisonls.add(vo);
        });
        rpage.setTotal(page.getTotal());
        rpage.setRecords(customerLiaisonls);
        return Result.result(rpage);
    }

    @PostMapping(value = "/mark_trash")
    @ApiOperation(value = "垃圾箱")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> mvTrashBox(MailMoveDTO dto) {
        if (Objects.isNull(dto.getEmailId()) && StringUtils.isEmpty(dto.getEmailIds())) {
            return Result.error("参数错误！");
        }
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
        uWrapper.set(EmailsEntity::getIsTrash, dto.getIsTrash());
        uWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
        if (Objects.nonNull(dto.getEmailId())) {
            uWrapper.eq(EmailsEntity::getId, dto.getEmailId());
        } else {
            uWrapper.in(EmailsEntity::getId, dto.getEmailIds());
        }
        emailsService.update(uWrapper);
        return Result.ok();
    }

    @ApiOperation(value = "彻底删除")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = Result.class)
    })
    @PostMapping("/deleteIds")
    public Result<?> deleteIds(Long[] ids) {
        if (Objects.isNull(ids)) {
            return Result.error("参数错误");
        }
        LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
        uWrapper.set(EmailsEntity::getIsDelete, Integer.valueOf(1));
        uWrapper.in(EmailsEntity::getId, Arrays.asList(ids));
        emailsService.update(uWrapper);
        return Result.ok();
    }

    @ApiOperation(value = "彻底删除草稿")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = Result.class)
    })
    @PostMapping("/deleteDraftIds")
    public Result<?> deleteDraftIds(Long[] ids) {
        if (Objects.isNull(ids)) {
            return Result.error("删除草稿");
        }
        LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
        uWrapper.in(EmailsEntity::getId, Arrays.asList(ids));
        emailsService.remove(uWrapper);
        return Result.ok();
    }

    @PostMapping(value = "/get_mail_detial")
    @ApiOperation(value = "获取详情接口")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> getMailDetial(Long mailId) {
        if (Objects.isNull(mailId)) {
            return Result.error("参数错误！");
        }
        EmailsEntity email = emailsService.getById(mailId);
        if (Objects.nonNull(email) && EmailBoxEnum.DRAFT.code.equals(email.getFolder())) {
            List<MailTempAttachmentEntity> atts = tempAttachmentService.list(new LambdaQueryWrapper<MailTempAttachmentEntity>().eq(MailTempAttachmentEntity::getEmailId, mailId));
            if (!CollectionUtils.isEmpty(atts)) {
                atts.forEach(e -> {
                    e.setFileSizeName(FileHelper.formatFileSize(e.getFileSize()));
                });
            }
            email.setAttachments(atts);
        } else {
            List<MailAttachmentEntity> atts = mailAttachmentService.list(new LambdaQueryWrapper<MailAttachmentEntity>().eq(MailAttachmentEntity::getEmailId, mailId));
            if (!CollectionUtils.isEmpty(atts)) {
                atts.forEach(e -> {
                    e.setFileSizeName(FileHelper.formatFileSize(e.getFileSize()));
                });
            }
            email.setAttachments(atts);
        }

        return Result.result(email);
    }

    @PostMapping(value = "/mv_custom_folder")
    @ApiOperation(value = "迁移邮件到自定义文件夹", notes = "迁移邮件到自定义文件夹")
    public Result getMailPortConfig(Long[] mailIds, Long folderId) {
        if (Objects.isNull(mailIds) || Objects.isNull(folderId)) {
            return Result.error("参数错误");
        }
        LambdaUpdateWrapper<EmailsEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(EmailsEntity::getCustomFolderId, folderId);
        updateWrapper.in(EmailsEntity::getId, Arrays.asList(mailIds));
        emailsService.update(updateWrapper);
        return Result.ok();
    }

    @PostMapping(value = "/del_custom_folder_mail")
    @ApiOperation(value = "获取邮箱端口配置", notes = "获取邮箱端口配置")
    public Result delCustomFolderMail(Long[] mailIds) {
        if (Objects.isNull(mailIds)) {
            return Result.error("参数错误");
        }
        LambdaUpdateWrapper<EmailsEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(EmailsEntity::getId, Arrays.asList(mailIds));
        updateWrapper.set(EmailsEntity::getCustomFolderId, null);
        emailsService.update(updateWrapper);
        return Result.ok();
    }

    @PostMapping(value = "/mark_star")
    @ApiOperation(value = "星标")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> takeStar(MailMoveDTO dto) {
        if (Objects.isNull(dto.getEmailId()) && StringUtils.isEmpty(dto.getEmailIds())) {
            return Result.error("参数错误！");
        }
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
        uWrapper.set(EmailsEntity::getIsStar, dto.getIsStar());
        uWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
        if (Objects.nonNull(dto.getEmailId())) {
            uWrapper.eq(EmailsEntity::getId, dto.getEmailId());
        } else {
            uWrapper.in(EmailsEntity::getId, dto.getEmailIds());
        }
        emailsService.update(uWrapper);
        return Result.ok();
    }

    @PostMapping(value = "/mark_read")
    @ApiOperation(value = "已读未读标记")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> markRead(MailMoveDTO dto) {
        if (Objects.isNull(dto.getEmailId()) && StringUtils.isEmpty(dto.getEmailIds())) {
            return Result.error("参数错误！");
        }
        LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
        uWrapper.set(EmailsEntity::getIsRead, dto.getIsRead());
        if (Objects.nonNull(dto.getEmailId())) {
            uWrapper.eq(EmailsEntity::getId, dto.getEmailId());
        } else {
            uWrapper.in(EmailsEntity::getId, dto.getEmailIds());
        }
        emailsService.update(uWrapper);
        return Result.ok();
    }

    @PostMapping(value = "/mark_reply_msg_id")
    @ApiOperation(value = "标记陌生客户回复不回复")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> markReplyMsgId(MailMoveDTO dto) {
        if (Objects.isNull(dto.getEmailId()) && StringUtils.isEmpty(dto.getEmailIds())) {
            return Result.error("参数错误！");
        }
        LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
        uWrapper.set(EmailsEntity::getReplyMsgId, dto.getReplyMsgId());
        if (Objects.nonNull(dto.getEmailId())) {
            uWrapper.eq(EmailsEntity::getId, dto.getEmailId());
        } else {
            uWrapper.in(EmailsEntity::getId, dto.getEmailIds());
        }
        emailsService.update(uWrapper);
        return Result.ok();
    }

    @PostMapping(value = "/mark_all_read")
    @ApiOperation(value = "已读未读标记")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> markAllRead() {
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        if (Objects.isNull(currentUserId)) {
            return Result.error("登录失效，请重新登陆!");
        }
        LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
        uWrapper.set(EmailsEntity::getIsRead, Integer.valueOf(1));
        uWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
        uWrapper.eq(EmailsEntity::getIsRead, Integer.valueOf(0));
        emailsService.update(uWrapper);
        return Result.ok();
    }

    @PostMapping(value = "/list_mail_attachment")
    @ApiOperation(value = "邮件附件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result listMailAttachment(AttachmentDTO dto) {

        Long currentUserId = LoginUserUtil.getCurrentUserId();
        SmtpPopSettingsEntity emailPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        if (Objects.isNull(emailPop)) {
            return Result.result(null);
        }

        QueryWrapper<MailAttachmentEntity> queryWrapper = new QueryWrapper();
        queryWrapper.eq("att.smtp_pop_id", emailPop.getId());

        if (StrUtil.isNotBlank(dto.getFileExt())) {
            if ("png".equals(dto.getFileExt())) {
                queryWrapper.in("att.file_ext", Arrays.asList("png", "jpg"));
            } else if ("video".equals(dto.getFileExt())) {
                queryWrapper.in("att.file_ext", Arrays.asList("mp4", "video"));
            } else if ("zip".equals(dto.getFileExt())) {
                queryWrapper.in("att.file_ext", Arrays.asList("zip", "rar", "7z"));
            } else if ("txt".equals(dto.getFileExt())) {
                queryWrapper.in("att.file_ext", Arrays.asList("pdf", "word", "excel"));
            } else {
                queryWrapper.eq("att.file_ext", dto.getFileExt());
            }
        }
        Page<MailAttachmentEntity> page = new Page<>(dto.getPageIndex(), dto.getPageSize());

        queryWrapper.eq("att.is_delete", CommonConstant.DEL_FLAG_0);
        queryWrapper.eq("e.smtp_pop_id", emailPop.getId());

        queryWrapper.orderByDesc("e.sent_date");

        IPage<MailAttachmentEntity> pageList = mailAttachmentService.pateList(page, queryWrapper);

        Map<Long, String> emailMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(pageList.getRecords())) {
            List<Long> mailIds = pageList.getRecords().stream().map(MailAttachmentEntity::getEmailId).collect(Collectors.toList());
            LambdaQueryWrapper<EmailsEntity> eQueryWrapper = new LambdaQueryWrapper<>();
            eQueryWrapper.in(EmailsEntity::getId, mailIds);
            List<EmailsEntity> emails = emailsService.list(eQueryWrapper);
            if (!CollectionUtils.isEmpty(emails)) {
                emailMap = emails.stream().collect(Collectors.toMap(EmailsEntity::getId, EmailsEntity::getSubject));
            }
            Map<Long, String> finalEmailMap = emailMap;
            pageList.getRecords().forEach(e -> {
                e.setFileSizeName(FileHelper.formatFileSize(e.getFileSize()));
                e.setSubject(finalEmailMap.get(e.getEmailId()));
            });
        }
        return Result.result(pageList);
    }


    @PostMapping(value = "/download_zip")
    @ApiOperation(value = "打包下载")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public void downloadZip(AttachmentDTO dto, HttpServletResponse response) {
        if (Objects.isNull(dto.getMailId()) && CollectionUtils.isEmpty(dto.getAttachmentIds())) {
            return;
        }
        String zipFilePath = mailFileProperties.getPath().getPath() + System.currentTimeMillis() + RandomGenerateHelper.generateRandomString(6) + ".zip";
        List<MailAttachmentEntity> attachments;
        if (Objects.nonNull(dto.getMailId())) {
            attachments = mailAttachmentService.list(new LambdaQueryWrapper<MailAttachmentEntity>().eq(MailAttachmentEntity::getEmailId, dto.getMailId()).eq(MailAttachmentEntity::getDownload, Integer.valueOf(1)));
        } else {
            attachments = mailAttachmentService.list(new LambdaQueryWrapper<MailAttachmentEntity>().in(MailAttachmentEntity::getId, dto.getAttachmentIds()).eq(MailAttachmentEntity::getDownload, Integer.valueOf(1)));
        }
        if (CollectionUtils.isEmpty(attachments)) {
            return;
        }
        try {
            ZipUtility.zipFiles(attachments, zipFilePath, mailFileProperties);
        } catch (IOException e) {
            return;
        }
        File downloadFile = new File(zipFilePath);
        try {
            FileInputStream inStream = new FileInputStream(downloadFile);
            // 设置响应头
            response.setContentType("application/zip");
            response.setContentLength((int) downloadFile.length());
            response.setHeader("Content-Disposition", "attachment; filename=\"" + downloadFile.getName() + "\"");
            // 获取输出流
            OutputStream outStream = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead;

            // 写入响应输出流
            while ((bytesRead = inStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            log.error("Error occurred while downloading the file: ", e);
        } finally {
            // 下载完成后删除临时ZIP文件
            if (downloadFile.exists()) {
                if (!downloadFile.delete()) {
                    System.err.println("Failed to delete the temporary file: " + zipFilePath);
                }
            }
        }
    }

    @PostMapping(value = "/download_url")
    @ApiOperation(value = "下载", notes = "下载")
    public Result downloadUrl(Long attachmentId) throws IOException {
        try {
            if (attachmentId == null) {
                return Result.error("附未找到");
            }
            MailAttachmentEntity attachment = mailAttachmentService.getById(attachmentId);
            if (attachment == null) {
                return Result.error("附未找到");
            }

            String url =  mailFileProperties.getPath().getPath() + File.separator + attachment.getFilePath();


            // String newFileName = attachment.getFilePath().replace("."+attachment.getFileCode(),"");
            File exportDir;
            String active = environment.getProperty("spring.profiles.active");
            String port =  environment.getProperty("server.port");
            if (active.equals("dev")) {
                exportDir = new File("D:\\mail\\tempfiles");
            } else {
                url = url.replace("\\", "/");
                exportDir = new File("/app/tempfiles");
            }
            Path filePath = Paths.get(url);
            if (!exportDir.exists()) {
                exportDir.mkdirs();
            }

            Path targetPath1;
            if (StrUtil.isNotBlank(attachment.getFileCode())) {
                targetPath1 = Paths.get(url.replace("."+attachment.getFileCode(),""));
            } else {
                targetPath1 = Paths.get(url);
            }
            String fileName = targetPath1.getFileName().toString();

            Path target = Paths.get(exportDir.getAbsolutePath());
            // 创建目标目录（如果不存在）
            if (!Files.exists(target.getParent())) {
                Files.createDirectories(target.getParent());
            }
            Path targetPath = target.resolve(fileName);
            Files.copy(filePath, targetPath, StandardCopyOption.REPLACE_EXISTING);

            // 2. 拼接 URL（这里假设映射后访问路径是 /export/）
            String fileUrl = "/static/file/" + targetPath.getFileName();

            String domainUrl = "";
            if(active.equals("prod")) {
                domainUrl = "https://sales.storlead.com"+fileUrl;
            } else if (active.equals("test")){
                domainUrl = "https://sales.test.storlead.com"+fileUrl;
            } else if (active.equals("dev")){
                domainUrl = "http://localhost:"+port+fileUrl;
            }
            return Result.result(domainUrl);
        } catch (Exception e) {
            log.error("download--error", e);
            return Result.error("附未找到");
        }
    }

    @PostMapping(value = "/draft_download_url")
    @ApiOperation(value = "下载", notes = "下载")
    public Result draft_download(Long attachmentId) throws IOException {
        try {
            if (attachmentId == null) {
                return Result.error("附未找到");
            }
            MailTempAttachmentEntity attachment = tempAttachmentService.getById(attachmentId);
            if (attachment == null) {
                return Result.error("附未找到");
            }

            String url =  mailFileProperties.getPath().getPath() + File.separator + attachment.getFilePath();

            File exportDir;
            String active = environment.getProperty("spring.profiles.active");
            String port =  environment.getProperty("server.port");
            if (active.equals("dev")) {
                exportDir = new File("D:\\mail\\tempfiles");
            } else {
                url = url.replace("\\", "/");
                exportDir = new File("/app/tempfiles");
            }
            Path filePath = Paths.get(url);
            if (!exportDir.exists()) {
                exportDir.mkdirs();
            }
            Path targetPath1;
            if (StrUtil.isNotBlank(attachment.getFileCode())) {
                targetPath1 = Paths.get(url.replace("."+attachment.getFileCode(),""));
            } else {
                targetPath1 = Paths.get(url);
            }
            String fileName = targetPath1.getFileName().toString();

            Path target = Paths.get(exportDir.getAbsolutePath());
            // 创建目标目录（如果不存在）
            if (!Files.exists(target.getParent())) {
                Files.createDirectories(target.getParent());
            }
            Path targetPath = target.resolve(fileName);
            Files.copy(filePath, targetPath, StandardCopyOption.REPLACE_EXISTING);

            // 2. 拼接 URL（这里假设映射后访问路径是 /export/）
            String fileUrl = "/static/file/" + targetPath.getFileName();

            String domainUrl = "";
            if(active.equals("prod")) {
                domainUrl = "https://sales.storlead.com"+fileUrl;
            } else if (active.equals("test")){
                domainUrl = "https://sales.test.storlead.com"+fileUrl;
            } else if (active.equals("dev")){
                domainUrl = "http://localhost:"+port+fileUrl;
            }
            return Result.result(domainUrl);
        } catch (Exception e) {
            log.error("download--error", e);
            return Result.error("附未找到");
        }
    }

    @PostMapping(value = "/draft_download")
    @ApiOperation(value = "下载", notes = "下载")
    public void draft_download(Long attachmentId, HttpServletResponse response) throws IOException {
        try {
            if (attachmentId == null) {
                return;
            }
            MailTempAttachmentEntity attachment = tempAttachmentService.getById(attachmentId);
            if (attachment == null) {
                return;
            }
            InputStream inputStream;
            String url = mailFileProperties.getPath().getPath() + attachment.getFilePath();
            inputStream = new BufferedInputStream(new FileInputStream(url));
            response.reset();
            response.setContentType("application/octet-stream;charset=utf-8");
            /*
             * 跨域配置
             * */
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
//        String filename = "测试.docx";
            String filename = attachment.getFileName() + "." + attachment.getFileExt();
            response.addHeader("content-disposition",
                    "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")
                            + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8"));
//		response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            byte[] b = new byte[1024];
            int len;
//从输入流中读取一定数量的字节，并将其存储在缓冲区字节数组中，读到末尾返回-1
            ServletOutputStream outputStream = response.getOutputStream();
            while ((len = inputStream.read(b)) > 0) {
                outputStream.write(b, 0, len);
            }
            inputStream.close();
            outputStream.close();
        } catch (Exception e) {
            log.error("download--error", e);
        }
    }

    @RequestMapping(value = "/download")
    @ApiOperation(value = "下载", notes = "下载")
    public void download(Long attachmentId, HttpServletResponse response) throws IOException {
        try {
            if (attachmentId == null) {
                return;
            }
            MailAttachmentEntity attachment = mailAttachmentService.getById(attachmentId);
            if (attachment == null) {
                return;
            }
            InputStream inputStream;
            String url = mailFileProperties.getPath().getPath() + attachment.getFilePath();
            if (Integer.valueOf(0).equals(attachment.getDownload())) {
                if (new File(url).exists()) {
                    LambdaUpdateWrapper<MailAttachmentEntity> attachmentUpdate = new LambdaUpdateWrapper<>();
                    attachmentUpdate.set(MailAttachmentEntity::getDownload, Integer.valueOf(1));
                    attachmentUpdate.eq(MailAttachmentEntity::getId, attachment.getId());
                    mailAttachmentService.update(attachmentUpdate);
                }
                //没有下载
                EmailsEntity email = emailsService.getById(attachment.getEmailId());
                SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getById(email.getSmtpPopId());
                inputStream = emailsService.loadEmailsFile(smtpPop, email, attachment.getFileName() + "." + attachment.getFileExt());
                if (Objects.isNull(inputStream)) {
                    return;
                }
                String path = mailFileProperties.getPath().getPath() + attachment.getFilePath();
                File file = new File(path);
                try (FileOutputStream output = new FileOutputStream(file)) {
                    inputStream.transferTo(output);
                }
                LambdaUpdateWrapper<MailAttachmentEntity> attachmentUpdate = new LambdaUpdateWrapper<>();
                attachmentUpdate.set(MailAttachmentEntity::getDownload, Integer.valueOf(1));
                attachmentUpdate.set(MailAttachmentEntity::getFileSize, file.length());
                attachmentUpdate.eq(MailAttachmentEntity::getId, attachment.getId());
                mailAttachmentService.update(attachmentUpdate);
            }
            inputStream = new BufferedInputStream(new FileInputStream(url));
            response.reset();
            /*
             * 跨域配置
             * */
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
//        String filename = "测试.docx";
            String filename = attachment.getFileName() + "." + attachment.getFileExt();

            String ext = attachment.getFileExt().toLowerCase();
            boolean inline = ext.equals("pdf")
                    || ext.equals("png")
                    || ext.equals("jpg")
                    || ext.equals("jpeg")
                    || ext.equals("gif");
            if (inline) {
                if ("pdf".equals(ext)) {
                    response.setContentType("application/pdf");
                } else {
                    response.setContentType("image/" + ext);
                }
            } else {
//                response.setContentType("application/octet-stream");
                response.setContentType("application/octet-stream;charset=utf-8");
            }
            String dispositionType = inline ? "inline" : "attachment";
            response.setHeader(
                    "Content-Disposition",
                    dispositionType + "; filename=" + URLEncoder.encode(filename, "UTF-8")
                            + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8"));

//            response.addHeader("content-disposition",
//                    "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")
//                            + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8"));
//		response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
            byte[] b = new byte[1024];
            int len;
//从输入流中读取一定数量的字节，并将其存储在缓冲区字节数组中，读到末尾返回-1
            ServletOutputStream outputStream = response.getOutputStream();
            while ((len = inputStream.read(b)) > 0) {
                outputStream.write(b, 0, len);
            }
            inputStream.close();
            outputStream.close();
        } catch (Exception e) {
            log.error("download--error", e);
        }
    }

    // 读取 InputStream 并计算其大小
    public int getAttachmentSize(InputStream inputStream) throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, bytesRead);
        }
        return byteArrayOutputStream.size();
    }

    public InputStream copyInputStream(InputStream original) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = original.read(buffer)) != -1) {
            byteArrayOutputStream.write(buffer, 0, bytesRead);
        }
        // 生成的字节数组可以用来创建多个 InputStream 副本
        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    }

    @PostMapping(value = "/mail_port_config")
    @ApiOperation(value = "获取邮箱端口配置", notes = "获取邮箱端口配置")
    public Result getMailPortConfig(String mailAccount) throws IOException {
        if (StrUtil.isBlank(mailAccount)) {
            return Result.result("参数错误");
        }
        LambdaQueryWrapper<MailServerPortConfigEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MailServerPortConfigEntity::getMailServerSuffix, EmailServiceChecker.getEmailService(mailAccount));
        queryWrapper.last("limit 1");
        MailServerPortConfigEntity portConfig = serverPortConfigService.getOne(queryWrapper);
        return Result.result(portConfig);
    }

    @PostMapping(value = "/get_unread_count")
    @ApiOperation(value = "获取邮箱未读数", notes = "获取邮箱未读数")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = NewMailCountTipVO.class)
    })
    public Result getUnReadCount() {
        Long currentUserId = LoginUserUtil.getCurrentUserId();
        SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        if (Objects.isNull(currentUserId) || Objects.isNull(smtpPop)) {
            return Result.result("请先配置邮箱");
        }
        NewMailCountTipVO newMailCountTipVO = emailsService.countMailSummaryNum(smtpPop.getId(), currentUserId);
        NewMailCountTipVO newMailCountTipVO1 = emailsService.countCustomerFollowUpMailNum(smtpPop.getId(), currentUserId);
        newMailCountTipVO.setKnownCount(newMailCountTipVO1.getKnownCount());
        newMailCountTipVO.setUnknownCount(newMailCountTipVO1.getUnknownCount());
        NewMailCountTipVO newMailCountTipVO2 = emailsService.countCustomerAndClueNumber(smtpPop.getId(), currentUserId);
        newMailCountTipVO.setCustomerCount(newMailCountTipVO2.getCustomerCount());
        newMailCountTipVO.setClueCount(newMailCountTipVO2.getClueCount());

        LambdaQueryWrapper<MailAttachmentEntity> attWrapper = new LambdaQueryWrapper();
        attWrapper.eq(MailAttachmentEntity::getSmtpPopId, smtpPop.getId());
        attWrapper.eq(MailAttachmentEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        Integer attCount = mailAttachmentService.count(attWrapper);
        newMailCountTipVO.setAttachmentCount(attCount);
        LambdaQueryWrapper<EmailsEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
        queryWrapper.eq(EmailsEntity::getSmtpPopId, smtpPop.getId());
        queryWrapper.eq(EmailsEntity::getFolder, EmailBoxEnum.INBOX.code);
        queryWrapper.eq(EmailsEntity::getIsTrash, Integer.valueOf(0));
        queryWrapper.eq(EmailsEntity::getIsRead, Integer.valueOf(0));
        queryWrapper.eq(EmailsEntity::getIsDelete, Integer.valueOf(0));
        queryWrapper.ne(EmailsEntity::getFrom, "system@storlead.com");
        Integer unReadCount = emailsService.count(queryWrapper);
        newMailCountTipVO.setUnReadCount(unReadCount);
        queryWrapper.select(EmailsEntity::getId);
        queryWrapper.orderByDesc(EmailsEntity::getId);
        queryWrapper.last("limit 1");


        LambdaQueryWrapper<EmailsEntity> countFolderWp = new LambdaQueryWrapper();
        countFolderWp.eq(EmailsEntity::getOwnerBy, currentUserId);
        countFolderWp.eq(EmailsEntity::getSmtpPopId, smtpPop.getId());
        countFolderWp.eq(EmailsEntity::getIsTrash, Integer.valueOf(0));
        countFolderWp.eq(EmailsEntity::getIsRead, Integer.valueOf(0));
        countFolderWp.eq(EmailsEntity::getIsDelete, Integer.valueOf(0));
        countFolderWp.isNotNull(EmailsEntity::getCustomFolderId);

        Integer countMyFolderNum = emailsService.count(countFolderWp);
        newMailCountTipVO.setFolderCount(countMyFolderNum);
        QueryWrapper countFolderGroupWp = new QueryWrapper();
        countFolderGroupWp.eq("owner_by", currentUserId);
        countFolderGroupWp.eq("smtp_pop_id", smtpPop.getId());
        countFolderGroupWp.eq("is_trash", Integer.valueOf(0));
        countFolderGroupWp.eq("is_read", Integer.valueOf(0));
        countFolderGroupWp.eq("is_delete", Integer.valueOf(0));
        countFolderGroupWp.isNotNull("custom_folder_id");
        countFolderGroupWp.select("custom_folder_id as folderId, COUNT(*) as folderCount")
                .groupBy("custom_folder_id");

        List<Map<String, Object>> countMaps = emailsService.listMaps(countFolderGroupWp);
        Map<Long, Integer> folderUnReadMap = new HashMap<>();
        for (Map<String, Object> map : countMaps) {
            folderUnReadMap.put(Long.valueOf(map.get("folderId").toString()), Integer.valueOf(map.get("folderCount").toString()));
        }

        newMailCountTipVO.setFolderUnReadMap(folderUnReadMap);
        return Result.result(newMailCountTipVO);
    }

    @PostMapping(value = "/get_new_mail")
    @ApiOperation(value = "获取未读和最新的邮件", notes = "获取邮箱未读数")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = NewMailCountTipVO.class)
    })
    public Result getNewMail() {

        Long currentUserId = LoginUserUtil.getCurrentUserId();
        SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
        if (Objects.isNull(currentUserId) || Objects.isNull(smtpPop)) {
            return Result.result("请先配置邮箱");
        }
        LambdaQueryWrapper<SmtpPopSettingsEntity> queryWrapper1 = new LambdaQueryWrapper();
        queryWrapper1.select(SmtpPopSettingsEntity::getId);
        queryWrapper1.eq(SmtpPopSettingsEntity::getIsDelete,0);
        queryWrapper1.eq(SmtpPopSettingsEntity::getOwnerBy,currentUserId);
        List<SmtpPopSettingsEntity> smtpPops = smtpPopSettingsService.list(queryWrapper1);

        NewMailTipVO tipVO = new NewMailTipVO();
        LambdaQueryWrapper<EmailsEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.select(EmailsEntity::getId);
        queryWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
        if (!CollectionUtils.isEmpty(smtpPops)) {
            queryWrapper.in(EmailsEntity::getSmtpPopId, smtpPops.stream().map(SmtpPopSettingsEntity::getId).collect(Collectors.toList()));
        }
        queryWrapper.eq(EmailsEntity::getFolder, EmailBoxEnum.INBOX.code);
        queryWrapper.eq(EmailsEntity::getIsTrash, Integer.valueOf(0));
        queryWrapper.eq(EmailsEntity::getIsRead, Integer.valueOf(0));
        queryWrapper.eq(EmailsEntity::getIsDelete, Integer.valueOf(0));
        queryWrapper.ne(EmailsEntity::getFrom, "system@storlead.com");
        Integer unReadCount = emailsService.count(queryWrapper);
        tipVO.setUnReadCount(unReadCount);
        queryWrapper.select(EmailsEntity::getId,EmailsEntity::getSubject);
        UserMailTrackRecordEntity record = mailTrackRecordService.getOne(new LambdaQueryWrapper<UserMailTrackRecordEntity>().eq(UserMailTrackRecordEntity::getOwnerBy, currentUserId).eq(UserMailTrackRecordEntity::getSmtpPopId, smtpPop.getId()).last("limit 1"));
        if (Objects.isNull(record)) {
            record = new UserMailTrackRecordEntity();
            queryWrapper.orderByDesc(EmailsEntity::getId);
            queryWrapper.last("limit 1");
            EmailsEntity maxEmail = emailsService.getOne(queryWrapper);
            if (Objects.nonNull(maxEmail)) {
                record.setMaxMailId(maxEmail.getId());
                record.setMessageId(maxEmail.getMessageId());
                record.setSmtpPopId(smtpPop.getId());
                record.setOwnerBy(currentUserId);
                mailTrackRecordService.saveOrUpdate(record);
            }
            queryWrapper.last("limit 5");
            if (unReadCount > 0) {
                List<EmailsEntity> entities = emailsService.list(queryWrapper);
                tipVO.setMaills(entities);
            }
            return Result.result(tipVO);
        } else {
            queryWrapper.gt(EmailsEntity::getId, record.getMaxMailId());
            queryWrapper.last("limit 5");
            List<EmailsEntity> entities = emailsService.list(queryWrapper);
            if (CollectionUtils.isEmpty(entities)) {
                return Result.result(tipVO);
            } else {
                tipVO.setMaills(entities);
                Optional<EmailsEntity> maxEntity = entities.stream()
                        .max(Comparator.comparing(EmailsEntity::getId));
                record.setMaxMailId(maxEntity.get().getId());
                mailTrackRecordService.saveOrUpdate(record);
                return Result.result(tipVO);
            }
        }
    }


    private static String formatDate(Date date) {
        if (date == null) return "N/A";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    private static String decodeAddresses(Address[] addresses) throws MessagingException {
        try {
            if (addresses == null) return "[]";
            String[] decodedAddresses = new String[addresses.length];
            for (int i = 0; i < addresses.length; i++) {
                decodedAddresses[i] = MimeUtility.decodeText(addresses[i].toString());
            }
            return Arrays.toString(decodedAddresses);
        } catch (Exception e) {
            return "";
        }
    }

//    @PostMapping(value = "/bind_mail_customer")
//    @ApiOperation(value = "修改客户关系")
//    @ApiResponses({
//            @ApiResponse(code = 200, message = "", response = Result.class)
//    })
//    public Result<?> repairMailCustomer(Long userId) {
//        if (Objects.isNull(userId)) {
//            return Result.error("参数错误");
//        }
//        SmtpPopSettingsEntity smtpPopSettings = smtpPopSettingsService.getDefaultSmtpPop(userId);
//        if (Objects.isNull(smtpPopSettings)) {
//            return Result.error("请先绑定邮箱");
//        }
//        LambdaQueryWrapper<EmailsEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.select(EmailsEntity::getId, EmailsEntity::getFrom, EmailsEntity::getRecipient, EmailsEntity::getRecipientCc, EmailsEntity::getFolder, EmailsEntity::getOwnerBy);
//        queryWrapper.eq(EmailsEntity::getIsDelete, Integer.valueOf(0));
//        queryWrapper.eq(EmailsEntity::getSmtpPopId, smtpPopSettings.getId());
//        queryWrapper.eq(EmailsEntity::getOwnerBy, userId);
//        List<EmailsEntity> emails = emailsService.list(queryWrapper);
//        if (CollectionUtils.isEmpty(emails)) {
//            return Result.error("无数据");
//        }
//
//        for (EmailsEntity entity : emails) {
//            if (Objects.isNull(entity.getInOutMark())) {
//                continue;
//            }
//            if (Integer.valueOf(1).equals(entity.getInOutMark())) {
//                emailsService.bindLiaisonMailCustomerIdByMailIdAndUserId(entity.getId(), entity.getFrom(), entity.getOwnerBy(), 1);
//            } else if (Integer.valueOf(2).equals(entity.getInOutMark())) {
//                String recipient = entity.getRecipient();
//                if (StrUtil.isNotBlank(entity.getRecipientCc())) {
//                    if (StrUtil.isNotBlank(recipient)) {
//                        recipient = recipient + "," + entity.getRecipientCc();
//                    } else {
//                        recipient = entity.getRecipientCc();
//                    }
//                }
//                emailsService.bindLiaisonMailCustomerIdByMailIdAndUserId(entity.getId(), recipient, entity.getOwnerBy(), 2);
//            }
//        }
//        return Result.result("操作完成");
//    }

//    @PostMapping(value = "/bind_mail_customer_all")
//    @ApiOperation(value = "修改客户关系")
//    @ApiResponses({
//            @ApiResponse(code = 200, message = "", response = Result.class)
//    })
//    public Result<?> repairMailCustomerAll() {
//
////        LambdaQueryWrapper<SmtpPopSettingsEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
////        lambdaQueryWrapper.eq(SmtpPopSettingsEntity::getIsDelete,0);
////        lambdaQueryWrapper.eq(SmtpPopSettingsEntity::getUseDefault,Integer.valueOf(1));
////        lambdaQueryWrapper.eq(SmtpPopSettingsEntity::getEnabled,1);
//        List<SmtpPopSettingsEntity> settingsEntities = smtpPopSettingsService.list();
//        if (CollectionUtils.isEmpty(settingsEntities)) {
//            return Result.error("请配置邮箱");
//        }
//
//        for (SmtpPopSettingsEntity smtpPop : settingsEntities) {
//            LambdaQueryWrapper<EmailsEntity> queryWrapper = new LambdaQueryWrapper<>();
//            queryWrapper.select(EmailsEntity::getId, EmailsEntity::getFrom, EmailsEntity::getRecipient, EmailsEntity::getRecipientCc, EmailsEntity::getFolder, EmailsEntity::getOwnerBy);
//            queryWrapper.eq(EmailsEntity::getIsDelete, Integer.valueOf(0));
//            queryWrapper.eq(EmailsEntity::getSmtpPopId, smtpPop.getId());
//            queryWrapper.eq(EmailsEntity::getOwnerBy, smtpPop.getOwnerBy());
//            List<EmailsEntity> emails = emailsService.list(queryWrapper);
//            if (CollectionUtils.isEmpty(emails)) {
//                continue;
//            }
//
//            for (EmailsEntity entity : emails) {
//                if (Integer.valueOf(1).equals(entity.getInOutMark())) {
//                    emailsService.bindLiaisonMailCustomerIdByMailIdAndUserId(entity.getId(), entity.getFrom(), entity.getOwnerBy(), 1);
//                } else if (Integer.valueOf(2).equals(entity.getInOutMark())) {
//                    String recipient = entity.getRecipient();
//                    if (StrUtil.isNotBlank(entity.getRecipientCc())) {
//                        if (StrUtil.isNotBlank(recipient)) {
//                            recipient = recipient + "," + entity.getRecipientCc();
//                        } else {
//                            recipient = entity.getRecipientCc();
//                        }
//                    }
//                    if (StrUtil.isNotBlank(recipient)) {
//                        emailsService.bindLiaisonMailCustomerIdByMailIdAndUserId(entity.getId(), recipient, entity.getOwnerBy(), 2);
//                    }
//                }
//            }
//        }
//        return Result.result("操作完成");
//    }

    @PostMapping(value = "/email_list")
    @ApiOperation(value = "客户列表-获取邮件")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
    })
    public Result<?> emailList(MailListDTO dto) {
        // 创建分页对象
        Page<CustomerEmailVo> pageParam = new Page<>(dto.getPageIndex(),dto.getPageSize());

        IPage<CustomerEmailVo> emailPage = emailsService.selectCustomerEmailPage(pageParam, dto);
        if (!CollectionUtils.isEmpty(emailPage.getRecords())) {
            List<Long> mailIds = emailPage.getRecords().stream().map(CustomerEmailVo::getMailId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(mailIds)) {
                QueryWrapper countAttachmentGroupWp = new QueryWrapper<>();
                countAttachmentGroupWp.in("email_id",mailIds);
                countAttachmentGroupWp.select("email_id as mailId, COUNT(*) as fileNum").groupBy("email_id");
                List<Map<Long, Object>> countMaps =  mailAttachmentService.listMaps(countAttachmentGroupWp);
                Map<Long, Integer> fileNumMap = new HashMap<>();
                for (Map<Long, Object> map : countMaps) {
                    fileNumMap.put(Long.valueOf(map.get("mailId").toString()), Integer.valueOf(map.get("fileNum").toString()));
                }
                emailPage.getRecords().forEach(e -> {
                    if (Objects.isNull(fileNumMap.get(e.getMailId()))) {
                        e.setAttachmentNum(0);
                    } else {
                        e.setAttachmentNum(fileNumMap.get(e.getMailId()));
                    }
                });
            }
        }

        return Result.result(emailPage);
    }


    @PostMapping(value = "/import_mail_eml")
    @ApiOperation(value = "导入邮件eml")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = Result.class)
    })
    public Result<?> importMailEml(HttpServletResponse response, @RequestParam(value = "file", required = true) MultipartFile file) {
        try {
            loadEmlFile(file);
        } catch (Exception e) {
            log.error("importMailEml error =", e);
        }
        return Result.ok();
    }

    @PostMapping(value = "/import_mail_eml_zip")
    @ApiResponses({
            @ApiResponse(code = 200, message = "", response = Result.class)
    })
    public Result<?> importMailEmlZip(HttpServletResponse response, @RequestParam(value = "file", required = true) MultipartFile file,String mobileNo) {
        try {
            // 解压压缩包
//            Path tempFilePath = saveTempFile(file);
//            FileExtractor.extractZip(tempFilePath);
            // 逐条解析解压后的邮件文件
            UserEntity user = userService.getUserByMobile(mobileNo);
            if (Objects.isNull(user)) {
                return Result.error("参数错误");
            }
            List<Message> messages = FileExtractor.processZipInMemory(file.getInputStream());
            if (CollectionUtils.isEmpty(messages)) {
                return Result.error("出现错误,没有解析出邮件");
            }
            List<SmtpPopSettingsEntity> settingsEntities = smtpPopSettingsService.list(new LambdaQueryWrapper<SmtpPopSettingsEntity>().eq(SmtpPopSettingsEntity::getIsDelete,CommonConstant.DEL_FLAG_0));
            if (CollectionUtils.isEmpty(settingsEntities)) {
                return Result.error("数据异常，无内部邮箱");
            }
            Set<String> internalMails = settingsEntities.stream().map(SmtpPopSettingsEntity::getEmailAddress).collect(Collectors.toSet());
            if (CollectionUtils.isEmpty(internalMails)) {
                return Result.error("数据异常，无内部邮箱");
            }

            List<EmailsEntity> entities = emailsService.analysisMailEmlls(messages,internalMails,user.getId());
            emailsService.updateFollowUpTime(entities, user.getId());



//            LambdaQueryWrapper<CustomerCompanyEntity> wrapper = new LambdaQueryWrapper<>();
//            wrapper.isNotNull(CustomerCompanyEntity::getCustomerId);
//            wrapper.like(CustomerCompanyEntity::getEmail, "@");
//            List<CustomerCompanyEntity> ccmails = customerCompanyService.list(wrapper);
//            if (!CollectionUtils.isEmpty(ccmails)) {
//               Set<String> mails = ccmails.stream().map(CustomerCompanyEntity::getEmail).collect(Collectors.toSet());
//                if (!CollectionUtils.isEmpty(ccmails)) {
//                    cusMails.addAll(mails);
//                }
//            }
//            LambdaQueryWrapper<LiaisonEntity> lwrapper = new LambdaQueryWrapper<>();
//            lwrapper.isNotNull(LiaisonEntity::getCustomerId);
//            lwrapper.like(LiaisonEntity::getName, "@");
//            List<LiaisonEntity> llmails = liaisonService.list();
//            if (!CollectionUtils.isEmpty(llmails)) {
//                Set<String> mails = llmails.stream().map(LiaisonEntity::getEmail).collect(Collectors.toSet());
//                if (!CollectionUtils.isEmpty(llmails)) {
//                    cusMails.addAll(mails);
//                }
//            }

//            List<EmailFolderRuleEntity> folderRules = folderRuleService.getUserFolderRules(smtpPop.getOwnerBy());
//            Set<String> blackList = blackListService.getBlackEmaillist(smtpPop.getOwnerBy());

//            if (!CollectionUtils.isEmpty(messages) && !CollectionUtils.isEmpty(cusMails)) {
//                emailsService.analysisMailEml(messages,cusMails);
//            }

//            CompletableFuture.runAsync(() -> {
//                updateFollowUpTime(entities, smtpPop.getOwnerBy());
//            });
//            List<Message> messages = FileExtractor.processZipFile(tempFilePath.toString());

//            loadEmlFile(file);
        } catch (Exception e) {
            log.error("importMailEml error =", e);
        }
        return Result.ok();
    }

    private Path saveTempFile(MultipartFile file) throws IOException {
        Path tempFilePath = Files.createTempFile("upload", ".zip");
        file.transferTo(tempFilePath.toFile());
        return tempFilePath;
    }

    // 加载 .eml 文件
    public void loadEmlFile(MultipartFile file) throws Exception {

        Set<String> cusMails = new HashSet<>();
        LambdaQueryWrapper<CustomerCompanyEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.isNotNull(CustomerCompanyEntity::getCustomerId);
        wrapper.like(CustomerCompanyEntity::getName, "@");
        List<CustomerCompanyEntity> ccmails = customerCompanyService.list(wrapper);
        if (!CollectionUtils.isEmpty(ccmails)) {
            Set<String> mails = ccmails.stream().map(CustomerCompanyEntity::getEmail).collect(Collectors.toSet());
            if (!CollectionUtils.isEmpty(ccmails)) {
                cusMails.addAll(mails);
            }
        }
        LambdaQueryWrapper<LiaisonEntity> lwrapper = new LambdaQueryWrapper<>();
        lwrapper.isNotNull(LiaisonEntity::getCustomerId);
        lwrapper.like(LiaisonEntity::getName, "@");
        List<LiaisonEntity> llmails = liaisonService.list();
        if (!CollectionUtils.isEmpty(llmails)) {
            Set<String> mails = llmails.stream().map(LiaisonEntity::getEmail).collect(Collectors.toSet());
            if (!CollectionUtils.isEmpty(llmails)) {
                cusMails.addAll(mails);
            }
        }

        // 配置邮件会话属性
        Properties props = new Properties();
        props.put("mail.imap.ssl.enable", "true");
        Session session = Session.getDefaultInstance(props);
        InputStream fileInputStream = file.getInputStream();
        MimeMessage mimeMessage = new MimeMessage(session, fileInputStream);
        emailsService.analysisMailEml(Arrays.asList(mimeMessage),cusMails,1L);

    }

//    @GetMapping(value = "/list.json")
//    @ApiOperation(value = "获取邮件")
//    public Result<?> list() {
//        LambdaQueryWrapper<EmailsEntity> wp = new LambdaQueryWrapper<>();
//        wp.last(" limit 100");
//        List<EmailsEntity> da = emailsService.list(wp);
//        return Result.result(da);
//    }
//
//    @GetMapping(value = "/listUrl")
//    @ApiOperation(value = "获取邮件")
//    public Result<?> listUrl() {
//
//        Map<String,String> mp = new HashMap<>();
//        mp.put("content","这是一个邮件数据集合");
//        mp.put("previewUrl","http://192.168.1.197:18090/sales/mail/list.json");
//        return Result.result(mp);
//    }
//
//    @GetMapping(value = "/v1/file/content")
//    @ApiOperation(value = "获取邮件")
//    public Result<?> listfile() {
//
//        Map<String,String> mp = new HashMap<>();
//        mp.put("url","https://storelead.oss-cn-shenzhen.aliyuncs.com/11_%E4%BF%9D%E5%AF%86%E5%8D%8F%E8%AE%AE_20191129105735.pdf");
//        return Result.result(mp);
//    }

//    @PostMapping(value = "/updateFollowUpTime")
//    @ApiOperation(value = "客户列表-获取邮件")
//    @ApiResponses({
//            @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
//    })
//    public Result<?> updateFollowUpTime(MailListDTO dto) {
//
////        select * from emails where smtp_pop_id = 29 and id >= 19285
//        LambdaQueryWrapper<EmailsEntity> lm = new LambdaQueryWrapper<>();
//        lm.eq(EmailsEntity::getSmtpPopId,29);
//        lm.ge(EmailsEntity::getId,83763);
//        lm.le(EmailsEntity::getId,89212);
//        List<EmailsEntity>  entities =  emailsService.list(lm);
//        emailsService.updateFollowUpTime(entities,408L);
//        return Result.ok();
//    }
}
