package org.egl_cepgl.pm.service;

import com.fasterxml.jackson.core.JsonParser;
import com.nimbusds.jose.shaded.json.JSONArray;
import com.nimbusds.jose.shaded.json.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.egl_cepgl.pm.dto.EmailDetailDTO;
import org.egl_cepgl.pm.dto.EmailDto;
import org.egl_cepgl.pm.dto.FileDto;
import org.egl_cepgl.pm.dto.ProjectDto;
import org.egl_cepgl.pm.model.Applicant;
import org.egl_cepgl.pm.model.Email;
import org.egl_cepgl.pm.model.Enterprise;
import org.egl_cepgl.pm.model.File;
import org.egl_cepgl.pm.repository.EmailRepository;
import org.egl_cepgl.pm.repository.FileRepository;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.transaction.Transactional;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.time.Year;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class EmailService {

    private final EmailRepository repository;
    private final FileService fileService;

    private final JavaMailSender emailSender;

    @Value("${spring.application.mail.sent.from}")
    private String fromUsr;

    private final RabbitTemplate rabbitTemplate;

    @Value("${rabbitmq.exchange.email.name}")
    private String emailExchange;

    @Value("${rabbitmq.binding.email.name}")
    private String emailRoutingKey;

    public void sendEmail(String[] to, String subject, String body) throws MessagingException
    {
        try{
            MimeMessage message = emailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
            helper.setTo(to);
            helper.setFrom(fromUsr);
            helper.setSubject(subject);
            helper.setText(body, true);
            emailSender.send(message);
        }catch (MailException e){
            log.error("Sending mail failed due to some error===="+e);
        }
    }

    @RabbitListener(queues = "email_queue")
    public void q(EmailDetailDTO emailDetailDTO) throws MessagingException {
        String[] to = emailDetailDTO.getTo();
        String subject = emailDetailDTO.getSubject();
        String body = generateEmailBody(emailDetailDTO);
        sendEmail(to, subject, body);
    }

    public String generateEmailBody(EmailDetailDTO emailDetailDTO)
    {
        String templateName = emailDetailDTO.getTemplateName();
        String template = loadEmailTemplate(templateName);
        String body = template;
        if (emailDetailDTO.getDynamicValue() != null) {
            for (Map.Entry<String, Object> entry : emailDetailDTO.getDynamicValue().entrySet()) {
                body = body.replace("{{" + entry.getKey() + "}}", entry.getValue().toString());
            }
        }
        return body;
    }

    public String loadEmailTemplate(String templateName)
    {
        ClassPathResource resource = new ClassPathResource("templates/emails/" + templateName + ".html");
        try {
            return StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            throw new RuntimeException("Error loading email template " + templateName, e);
        }
    }

    //@Transactional
    public void sendEmail(EmailDto emailData)
    {
        Email eml= new Email();
        eml.setEmail_to(emailData.getEmail_to().toString());
        eml.setEmail_cc(emailData.getEmail_cc().toString());
        eml.setSubject(emailData.getSubject());
        eml.setMessage(emailData.getMessage());
        eml.setAdmin_kcloak(emailData.getAdmin_kcloak());
        //eml.setFiles(emailData.getFiles().stream().map(FileDto::toEntity).collect(Collectors.toSet()));
        this.convertAndSendEmail(emailData);
//        Email em= this.repository.save(eml);
//        em.getFiles().addAll(eml.getFiles());
        //return this.repository.save(eml);
    }

    public EmailDetailDTO convertAndSendEmail(EmailDto email)
    {
        List<String> fls= new ArrayList<String>();
        if(email.getFiles().size() > 0){
            for (File file : email.getFiles().stream().map(FileDto::toEntity).collect(Collectors.toList())) {
                Path filePath = fileService.loadFileAsResource(file.getNamep());
                fls.add("<p><a href='"+filePath+"'>"+file.getNamep()+"</a></p>");
            }
        }
        Map<String, Object> mailData = Map.of(
                "files", fls,
                "copyright","© 1970 - "+ Year.now().getValue()+" EGL. Tous droits réservés.",
                "message", email.getMessage());

        EmailDetailDTO em= new EmailDetailDTO();
        em.setTo(email.getEmail_to());
        em.setCc(email.getEmail_cc());
        em.setSubject(email.getSubject());
        em.setTemplateName("classic_email");
        em.setDynamicValue(mailData);
        rabbitTemplate.convertAndSend(emailExchange, emailRoutingKey, em);
        return em;
    }

}
