package com.ai.da.common.utils;

import com.ai.da.common.constant.CommonConstant;
import com.ai.da.model.dto.BasicEmailParamDTO;
import com.alibaba.fastjson.JSONObject;
import com.sun.mail.smtp.SMTPTransport;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.InputStreamSource;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.*;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
public class MailUtil {

    @Resource
    private JavaMailSender javaMailSender;

    @Resource
    private TemplateEngine templateEngine;

    /**
     * 发送邮件 - 默认发件人
     *
     * @param basicEmailParamDTO 发送邮件所需参数
     * @param inputStreamSource  附件（如果有）
     */
    public int sendMail(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource) throws MessagingException {
        MimeMessage mimeMessage = createSimpleMail(basicEmailParamDTO, fileName, inputStreamSource);
        // 提取配置
        String host;
        String username;
        String password;
        if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getServiceAddress())) {
            host = ((JavaMailSenderImpl) javaMailSender).getHost();
        } else {
            host = basicEmailParamDTO.getServiceAddress();
        }
        if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getSenderUser())) {
            username = ((JavaMailSenderImpl) javaMailSender).getUsername();
        } else {
            username = basicEmailParamDTO.getSenderUser();
        }
        if (StringUtil.isNullOrEmpty(basicEmailParamDTO.getServiceAddress())) {
            password = ((JavaMailSenderImpl) javaMailSender).getPassword();
        } else {
            password = basicEmailParamDTO.getPassword();
        }
        return sendMail(mimeMessage, host, username, password);
    }

    private int sendMail(MimeMessage mimeMessage, String host, String username, String password) throws MessagingException {
        SMTPTransport transport = null;
        try {
            // 获取 SMTPTransport
            transport = (SMTPTransport) mimeMessage.getSession().getTransport("smtp");
            // 连接到 SMTP 服务器
            transport.connect(host, username, password);
            // 发送邮件
            transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
            // 获取 SMTP 服务器的响应
            String lastServerResponse = transport.getLastServerResponse();
            int lastReturnCode = transport.getLastReturnCode();

            log.info("SMTP 状态码: {}, SMTP 服务器响应: {}", lastReturnCode, lastServerResponse);
            return lastReturnCode;
        } catch (MailException | MessagingException e) {
            // 记录日志或执行其他补偿逻辑
            log.info("邮件发送失败：{}", e.getMessage());
        } finally {
            // 关闭连接
            assert transport != null;
            transport.close();
        }
        return 0;
    }

    /**
     * 创建一封邮件
     *
     * @param basicEmailParamDTO 创建邮件需要的参数
     * @param inputStreamSource  附件（如果有）
     * @return 一封邮件
     */
    private MimeMessage createSimpleMail(BasicEmailParamDTO basicEmailParamDTO, String fileName, InputStreamSource inputStreamSource) throws MessagingException {
        // 创建邮件对象
        MimeMessage message = javaMailSender.createMimeMessage();
        // 使用 MimeMessageHelper 简化邮件内容和附件的设置
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true);
        // 设置发件人
        mimeMessageHelper.setFrom(new InternetAddress(basicEmailParamDTO.getSenderUserMail()));
        // 设置收件人
        mimeMessageHelper.setTo(basicEmailParamDTO.getMailTo());
        // 设置抄送人
        if (basicEmailParamDTO.getCc() != null && basicEmailParamDTO.getCc().length > 0) {
            mimeMessageHelper.setCc(basicEmailParamDTO.getCc());
        }
        // 设置暗送人
        if (basicEmailParamDTO.getBcc() != null && basicEmailParamDTO.getBcc().length > 0) {
            mimeMessageHelper.setBcc(basicEmailParamDTO.getBcc());
        }
        // 设置邮件主题
        mimeMessageHelper.setSubject(basicEmailParamDTO.getSubject());
        // 设置邮件内容（HTML 格式）
        mimeMessageHelper.setText(basicEmailParamDTO.getContent(), true);
        // 设置附件
        if (inputStreamSource != null) {
            mimeMessageHelper.addAttachment(fileName, inputStreamSource);
        }
        return message;
    }


    /**
     * 设置实体参数
     *
     * @param mailTo     接收邮件的邮箱地址
     * @param jsonObject 模板中变量的值
     * @return 返回一个MailEntity
     * @throws AddressException 邮箱地址值异常
     */
    public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, JSONObject jsonObject, String templatePath, String title) throws AddressException {
        BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
//        basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
        basicEmailParamDTO.setSenderUserMail(CommonConstant.senderEmail);
        basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
        basicEmailParamDTO.setSubject(title);
        // todo 邮件模板不存在的报错与重试机制
        basicEmailParamDTO.setContent(setContent(jsonObject, templatePath));
        return basicEmailParamDTO;
    }

    public BasicEmailParamDTO setBasicEmailParams(List<String> mailTo, String title) throws AddressException {
        BasicEmailParamDTO basicEmailParamDTO = new BasicEmailParamDTO();
        basicEmailParamDTO.setSenderUserMail("info@aida.com.hk");
        basicEmailParamDTO.setMailTo(getInternetAddressList(mailTo));
        basicEmailParamDTO.setSubject(title);
        return basicEmailParamDTO;
    }

    /**
     * 将地址转换为InternetAddress类型
     *
     * @param addressList 普通的地址字符串列表
     * @return InternetAddress类型的地址列表
     * @throws AddressException 地址异常
     */
    public InternetAddress[] getInternetAddressList(List<String> addressList) throws AddressException {
        InternetAddress[] toAddress = new InternetAddress[addressList.size()];
        for (String address : addressList) {
            toAddress[addressList.indexOf(address)] = new InternetAddress(address);
        }
        return toAddress;
    }

    public String setContent(JSONObject jsonObject, String templatePath) {
        Context context = new Context();
        if (Objects.nonNull(jsonObject)) {
            for (String key : jsonObject.keySet()) {
                context.setVariable(key, jsonObject.get(key));
            }
        }
        return templateEngine.process(templatePath, context);
    }

}
