package com.iqser.red.service.persistence.management.v1.processor.service;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Properties;

import jakarta.mail.Address;
import jakarta.mail.Message;
import jakarta.mail.Multipart;
import jakarta.mail.internet.AddressException;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMultipart;

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;

import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.SMTPConfiguration;

import lombok.extern.slf4j.Slf4j;

/*
 * Logic Copied from KeyCloak since we need to test sending an e-mail the same way KeyCloak Does
 */
@Slf4j
@Service
public class EmailService {

    public void send(SMTPConfiguration smtpConfiguration, String toAddress, String subject, String textBody) {

        try {

            var sender = getJavaMailSender(smtpConfiguration);

            String from = smtpConfiguration.getFrom();
            String fromDisplayName = smtpConfiguration.getFromDisplayName();
            String replyTo = smtpConfiguration.getReplyTo();
            String replyToDisplayName = smtpConfiguration.getReplyToDisplayName();

            var msg = sender.createMimeMessage();

            Multipart multipart = new MimeMultipart("alternative");

            if (textBody != null) {
                MimeBodyPart textPart = new MimeBodyPart();
                textPart.setText(textBody, "UTF-8");
                multipart.addBodyPart(textPart);
            }

            msg.setFrom(toInternetAddress(from, fromDisplayName));

            msg.setReplyTo(new Address[]{toInternetAddress(from, fromDisplayName)});
            if (replyTo != null && !replyTo.isEmpty()) {
                msg.setReplyTo(new Address[]{toInternetAddress(replyTo, replyToDisplayName)});
            }

            msg.setHeader("To", toAddress);
            msg.setSubject(subject, "utf-8");
            msg.setContent(multipart);
            msg.saveChanges();
            msg.setSentDate(new Date());
            msg.setRecipients(Message.RecipientType.TO, toAddress);

            sender.send(msg);
        } catch (Exception e) {
            throw new BadRequestException("Failed to send e-mail", e);
        }
    }


    public JavaMailSender getJavaMailSender(SMTPConfiguration smtpConfiguration) {

        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost(smtpConfiguration.getHost());
        mailSender.setPort(smtpConfiguration.getPort());

        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtp.timeout", "10000");
        props.setProperty("mail.smtp.connectiontimeout", "10000");

        if (smtpConfiguration.isAuth()) {
            mailSender.setUsername(smtpConfiguration.getUser());
            mailSender.setPassword(smtpConfiguration.getPassword());
            props.put("mail.smtp.auth", "true");
        }

        if (smtpConfiguration.isSsl()) {
            props.setProperty("mail.smtp.ssl.enable", "true");
        }

        if (smtpConfiguration.isStarttls()) {
            props.setProperty("mail.smtp.starttls.enable", "true");
        }

        return mailSender;
    }


    protected InternetAddress toInternetAddress(String email, String displayName) throws UnsupportedEncodingException, AddressException {

        if (email == null || "".equals(email.trim())) {
            throw new BadRequestException("Please provide a valid address");
        }
        if (displayName == null || "".equals(displayName.trim())) {
            return new InternetAddress(email);
        }
        return new InternetAddress(email, displayName, "utf-8");
    }

}
