package com.zsc.edu.gateway.framework.message.email;


import com.zsc.edu.gateway.modules.attachment.service.AttachmentService;
import com.zsc.edu.gateway.modules.message.entity.Notice;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.AddressException;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;

import java.io.IOException;
import java.io.StringWriter;
import java.util.Objects;
import java.util.Set;


/**
 * @author pegnzheng
 */
@AllArgsConstructor
@Component
public class EmailSender {

    private final static String TEMPLATE = "message.ftl";

    private final EmailProperties config;
    private final Configuration freemarkerConfig;
    @Resource
    private final JavaMailSender sender;
    private final AttachmentService attachmentService;

    @Async
    public void send(String email, Notice notice) {
        if (StringUtils.hasText(email)) {
            return;
        }
        InternetAddress to;
        try {
            to = new InternetAddress(email);
            to.validate();
        } catch (AddressException e) {
            return;
        }
        send(new InternetAddress[]{to}, notice);
    }

    @Async
    public void send(Set<String> emails, Notice notice) {
        InternetAddress[] to = emails.stream().filter(Objects::nonNull).map(email ->
        {
            try {
                return new InternetAddress(email);
            } catch (AddressException e) {
                return null;
            }
        }).filter(Objects::nonNull).filter(internetAddress -> {
            try {
                internetAddress.validate();
            } catch (AddressException e) {
                return false;
            }
            return true;
        }).toArray(InternetAddress[]::new);
        if (to.length == 0) {
            return;
        }
        send(to, notice);
    }

    private void send(InternetAddress[] to, Notice notice) {
        try {
            MimeMessage mimeMessage = sender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setTo(to);
            helper.setFrom(config.username);
            helper.setSubject(notice.getTitle());
            if (notice.html) {
                StringWriter sw = new StringWriter();
                Template tp = freemarkerConfig.getTemplate(TEMPLATE, "UTF-8");
                tp.process(notice, sw);
                helper.setText(sw.toString(), true);
            } else {
                helper.setText(notice.content);
            }
//            if (Objects.nonNull(message.attachments)) {
//                for (Attachment attachment : message.attachments) {
//                    helper.addAttachment(attachment.fileName, attachmentService.loadAsResource(attachment.id), attachment.mimeType);
//                }
//            }
            sender.send(mimeMessage);
        } catch (MessagingException | IOException | TemplateException e) {
            e.printStackTrace();
        }
    }
}
