package com.alttd.altitudeweb.services.mail;

import com.alttd.altitudeweb.database.litebans.HistoryRecord;
import com.alttd.altitudeweb.database.web_db.forms.Appeal;
import com.alttd.altitudeweb.database.web_db.forms.DiscordAppeal;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;

import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

@Slf4j
@Service
@RequiredArgsConstructor
public class AppealMail {

    private final JavaMailSender mailSender;
    private final SpringTemplateEngine templateEngine;

    @Value("${spring.mail.username}")
    private String fromEmail;

    private static final String APPEAL_EMAIL = "appeal@alttd.com";

    /**
     * Sends an email notification about the appeal to both the user and the appeals team.
     *
     * @param appeal The appeal object containing all necessary information
     */
    public void sendAppealNotification(DiscordAppeal appeal, String username) {
        try {
            sendEmailToAppealsTeam(appeal, username);

            log.info("Discord Appeal notification emails sent successfully for appeal ID: {}", appeal.id());
        } catch (Exception e) {
            log.error("Failed to send discord appeal notification emails for appeal ID: {}", appeal.id(), e);
        }
    }
    /**
     * Sends an email notification about the appeal to both the user and the appeals team.
     *
     * @param appeal The appeal object containing all necessary information
     */
    public void sendAppealNotification(Appeal appeal, HistoryRecord history) {
        try {
            sendEmailToAppealsTeam(appeal, history);

            log.info("Appeal notification emails sent successfully for appeal ID: {}", appeal.id());
        } catch (Exception e) {
            log.error("Failed to send appeal notification emails for appeal ID: {}", appeal.id(), e);
        }
    }

    private void sendEmailToAppealsTeam(Appeal appeal, HistoryRecord history) throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);

        helper.setFrom(fromEmail);
        helper.setTo(APPEAL_EMAIL);
        helper.setReplyTo(appeal.email());
        helper.setSubject("New Appeal Submitted - " + appeal.username());

        Context context = new Context();
        context.setVariable("appeal", appeal);
        context.setVariable("history", history);
        context.setVariable("createdAt", appeal.createdAt()
                                               .atZone(ZoneId.of("UTC"))
                                               .format(DateTimeFormatter.ofPattern("yyyy MMMM dd hh:mm a '(UTC)'")));
        context.setVariable("active", history.getUntil() <= 0 || history.getUntil() > System.currentTimeMillis());
        String content = templateEngine.process("appeal-email", context);

        helper.setText(content, true);
        mailSender.send(message);
    }

    private void sendEmailToAppealsTeam(DiscordAppeal appeal, String username) throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = getAppealMimeMessageHelper(appeal, message);

        Context context = new Context();
        context.setVariable("appeal", appeal);
        context.setVariable("createdAt", appeal.createdAt()
                                               .atZone(ZoneId.of("UTC"))
                                               .format(DateTimeFormatter.ofPattern("yyyy MMMM dd hh:mm a '(UTC)'")));

        context.setVariable("minecraftName", username);
        String content = templateEngine.process("discord-appeal-email", context);

        helper.setText(content, true);
        mailSender.send(message);
    }

    private MimeMessageHelper getAppealMimeMessageHelper(DiscordAppeal appeal, MimeMessage message) throws MessagingException {
        MimeMessageHelper helper = new MimeMessageHelper(message, true);

        helper.setFrom(fromEmail);
        helper.setTo(APPEAL_EMAIL);
        helper.setReplyTo(appeal.email());
        helper.setSubject("New Appeal Submitted - " + appeal.discordUsername());
        return helper;
    }

}
