GmailEmailService.java

package com.ctrlbuy.webshop.service.impl;

import com.ctrlbuy.webshop.model.Order;
import com.ctrlbuy.webshop.model.OrderItem;
import com.ctrlbuy.webshop.security.entity.User;
import com.ctrlbuy.webshop.service.EmailService;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Primary;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;

@Service
@Primary
@ConditionalOnProperty(name = "app.email.mock.enabled", havingValue = "false", matchIfMissing = false)
public class GmailEmailService implements EmailService {

    private static final Logger logger = LoggerFactory.getLogger(GmailEmailService.class);

    @Autowired
    private JavaMailSender mailSender;

    @Value("${app.email.from:noreply@ctrlbuy.com}")
    private String fromEmail;

    @Value("${app.base.url:http://localhost:8080}")
    private String baseUrl;

    @Override
    public void sendVerificationEmail(User user, String token) {
        sendVerificationEmail(user.getEmail(), token, user.getFirstName());
    }

    @Override
    public void sendVerificationEmail(String email, String token, String firstName) {
        try {
            String verificationUrl = baseUrl + "/verify?token=" + token;
            String subject = "Verifiera ditt konto - CtrlBuy";

            String htmlContent = createVerificationEmailHtml(firstName, verificationUrl);

            sendHtmlEmail(email, subject, htmlContent);

            logger.info("✅ Verifieringsmail skickat till: {}", email);
        } catch (Exception e) {
            logger.error("❌ Fel vid skickande av verifieringsmail till: {}", email, e);
            // Fallback till mock-beteende vid fel
            logSimulatedEmail("verifieringsmail", email);
        }
    }

    @Override
    public boolean sendVerificationEmail(String email, String token) {
        try {
            sendVerificationEmail(email, token, "Användare");
            return true;
        } catch (Exception e) {
            logger.error("Fel vid skickande av verifieringsmail", e);
            return false;
        }
    }

    @Override
    public void sendWelcomeEmail(User user) {
        try {
            String subject = "Välkommen till CtrlBuy!";
            String htmlContent = createWelcomeEmailHtml(user.getFirstName());

            sendHtmlEmail(user.getEmail(), subject, htmlContent);

            logger.info("✅ Välkomstmail skickat till: {}", user.getEmail());
        } catch (Exception e) {
            logger.error("❌ Fel vid skickande av välkomstmail till: {}", user.getEmail(), e);
            logSimulatedEmail("välkomstmail", user.getEmail());
        }
    }

    @Override
    public void sendPasswordResetEmail(User user, String resetToken) {
        sendPasswordResetEmail(user.getEmail(), resetToken, user.getFirstName());
    }

    @Override
    public void sendPasswordResetEmail(String email, String resetToken, String firstName) {
        try {
            String resetUrl = baseUrl + "/reset-password?token=" + resetToken;
            String subject = "Återställ ditt lösenord - CtrlBuy";

            String htmlContent = createPasswordResetEmailHtml(firstName, resetUrl);

            sendHtmlEmail(email, subject, htmlContent);

            logger.info("✅ Lösenordsåterställning skickat till: {}", email);
            logger.info("🔗 Reset-länk: {}", resetUrl);
        } catch (Exception e) {
            logger.error("❌ Fel vid skickande av lösenordsåterställning till: {}", email, e);
            // Fallback - logga länken så den kan användas manuellt
            String resetUrl = baseUrl + "/reset-password?token=" + resetToken;
            logger.info("📧 =========================");
            logger.info("📧 LÖSENORDSÅTERSTÄLLNING (FALLBACK)");
            logger.info("📧 =========================");
            logger.info("📧 Till: {} ({})", email, firstName);
            logger.info("📧 Reset-länk: {}", resetUrl);
            logger.info("📧 Token: {}", resetToken);
            logger.info("📧 =========================");
            logger.info("📧 KOPIERA LÄNKEN OVAN FÖR ATT TESTA!");
            logger.info("📧 =========================");
            logger.info("✅ Reset-mail simulerat skickat till: {}", email);
        }
    }

    @Override
    public boolean sendPasswordResetEmail(String email, String resetToken) {
        try {
            sendPasswordResetEmail(email, resetToken, "Användare");
            return true;
        } catch (Exception e) {
            logger.error("Fel vid skickande av reset-mail", e);
            return false;
        }
    }

    @Override
    public void sendOrderConfirmationEmail(User user, String orderNumber) {
        try {
            String subject = "Orderbekräftelse #" + orderNumber + " - CtrlBuy";
            String htmlContent = createOrderConfirmationEmailHtml(user.getFirstName(), orderNumber);

            sendHtmlEmail(user.getEmail(), subject, htmlContent);

            logger.info("✅ Orderbekräftelse skickat till: {} för order: {}", user.getEmail(), orderNumber);
        } catch (Exception e) {
            logger.error("❌ Fel vid skickande av orderbekräftelse till: {}", user.getEmail(), e);
            logSimulatedEmail("orderbekräftelse", user.getEmail());
        }
    }

    @Override
    public void sendOrderConfirmation(Order order, String email) {
        try {
            String subject = "Orderbekräftelse #" + order.getOrderNumber() + " - CtrlBuy";
            String htmlContent = createDetailedOrderConfirmationEmailHtml(order);

            sendHtmlEmail(email, subject, htmlContent);

            logger.info("✅ Orderbekräftelse skickat till: {} för order: {}", email, order.getOrderNumber());
        } catch (Exception e) {
            logger.error("❌ Fel vid skickande av orderbekräftelse till: {}", email, e);
            logger.info("📧 Orderbekräftelse simulerat skickat till: {} för order: {}",
                    email, order.getOrderNumber());
        }
    }

    @Override
    public boolean sendOrderConfirmation(String email, Order order) {
        try {
            sendOrderConfirmation(order, email);
            return true;
        } catch (Exception e) {
            logger.error("Fel vid skickande av orderbekräftelse", e);
            return false;
        }
    }

    @Override
    public void sendAccountDeletionNotification(User deletedUser, String adminUsername, String reason) {
        try {
            String subject = "Ditt konto har tagits bort - CtrlBuy";
            String htmlContent = createAccountDeletionEmailHtml(deletedUser.getFirstName(), adminUsername, reason);

            sendHtmlEmail(deletedUser.getEmail(), subject, htmlContent);

            logger.info("✅ Kontoborttagning-meddelande skickat till: {}", deletedUser.getEmail());
        } catch (Exception e) {
            logger.error("❌ Fel vid skickande av kontoborttagning-meddelande till: {}", deletedUser.getEmail(), e);
            logSimulatedEmail("kontoborttagning-meddelande", deletedUser.getEmail());
        }
    }

    @Override
    public void sendAccountDeactivationNotification(User deactivatedUser, String adminUsername, String reason) {
        try {
            String subject = "Ditt konto har deaktiverats - CtrlBuy";
            String htmlContent = createAccountDeactivationEmailHtml(deactivatedUser.getFirstName(), adminUsername, reason);

            sendHtmlEmail(deactivatedUser.getEmail(), subject, htmlContent);

            logger.info("✅ Kontodeaktivering-meddelande skickat till: {}", deactivatedUser.getEmail());
        } catch (Exception e) {
            logger.error("❌ Fel vid skickande av kontodeaktivering-meddelande till: {}", deactivatedUser.getEmail(), e);
            logSimulatedEmail("kontodeaktivering-meddelande", deactivatedUser.getEmail());
        }
    }

    @Override
    public void sendAccountReactivationNotification(User reactivatedUser, String adminUsername) {
        try {
            String subject = "Ditt konto har aktiverats - CtrlBuy";
            String htmlContent = createAccountReactivationEmailHtml(reactivatedUser.getFirstName(), adminUsername);

            sendHtmlEmail(reactivatedUser.getEmail(), subject, htmlContent);

            logger.info("✅ Kontoaktivering-meddelande skickat till: {}", reactivatedUser.getEmail());
        } catch (Exception e) {
            logger.error("❌ Fel vid skickande av kontoaktivering-meddelande till: {}", reactivatedUser.getEmail(), e);
            logSimulatedEmail("kontoaktivering-meddelande", reactivatedUser.getEmail());
        }
    }

    @Override
    public boolean testEmailConnection() {
        try {
            // Skicka ett enkelt test-email
            String testEmail = fromEmail;
            String subject = "Test Email Connection - CtrlBuy";
            String content = "<h1>Email Connection Test</h1><p>Detta är ett test av email-anslutningen.</p>";

            sendHtmlEmail(testEmail, subject, content);

            logger.info("✅ Email-anslutning testad framgångsrikt");
            return true;
        } catch (Exception e) {
            logger.error("❌ Email-anslutning misslyckades", e);
            return false;
        }
    }

    @Override
    public boolean isConfigured() {
        return mailSender != null && fromEmail != null && !fromEmail.isEmpty();
    }

    // === PRIVATA HJÄLPMETODER ===

    private void sendHtmlEmail(String to, String subject, String htmlContent) throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

        helper.setFrom(fromEmail);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(htmlContent, true);

        logger.debug("📧 Skickar email till: {} med ämne: {}", to, subject);
        mailSender.send(message);
        logger.debug("📧 Email skickad framgångsrikt");
    }

    private void logSimulatedEmail(String type, String email) {
        logger.info("📧 {} simulerat skickat till: {}", type, email);
    }

    // === HTML EMAIL TEMPLATES ===

    private String createVerificationEmailHtml(String firstName, String verificationUrl) {
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>Verifiera ditt konto</title>
            </head>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h1 style="color: #28a745;">Välkommen till CtrlBuy!</h1>
                    <p>Hej %s,</p>
                    <p>Tack för att du registrerat dig hos oss! För att slutföra din registrering, klicka på länken nedan:</p>
                    <div style="text-align: center; margin: 30px 0;">
                        <a href="%s" style="background-color: #28a745; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;">Verifiera mitt konto</a>
                    </div>
                    <p>Om länken inte fungerar, kopiera och klistra in denna URL i din webbläsare:</p>
                    <p style="background-color: #f8f9fa; padding: 10px; border-radius: 5px; word-break: break-all;">%s</p>
                    <p>Med vänliga hälsningar,<br>CtrlBuy-teamet</p>
                </div>
            </body>
            </html>
            """.formatted(firstName, verificationUrl, verificationUrl);
    }

    private String createPasswordResetEmailHtml(String firstName, String resetUrl) {
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>Återställ ditt lösenord</title>
            </head>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h1 style="color: #dc3545;">Återställ ditt lösenord</h1>
                    <p>Hej %s,</p>
                    <p>Du har begärt att återställa ditt lösenord. Klicka på länken nedan för att sätta ett nytt lösenord:</p>
                    <div style="text-align: center; margin: 30px 0;">
                        <a href="%s" style="background-color: #dc3545; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;">Återställ lösenord</a>
                    </div>
                    <p>Om länken inte fungerar, kopiera och klistra in denna URL i din webbläsare:</p>
                    <p style="background-color: #f8f9fa; padding: 10px; border-radius: 5px; word-break: break-all;">%s</p>
                    <p><strong>Observera:</strong> Denna länk är giltig i 24 timmar.</p>
                    <p>Om du inte begärde denna återställning, ignorera detta email.</p>
                    <p>Med vänliga hälsningar,<br>CtrlBuy-teamet</p>
                </div>
            </body>
            </html>
            """.formatted(firstName, resetUrl, resetUrl);
    }

    private String createWelcomeEmailHtml(String firstName) {
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>Välkommen till CtrlBuy</title>
            </head>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h1 style="color: #28a745;">Välkommen till CtrlBuy! 🎉</h1>
                    <p>Hej %s,</p>
                    <p>Ditt konto har nu verifierats och du är redo att börja handla!</p>
                    <p>Vi erbjuder de senaste teknikprodukterna till fantastiska priser.</p>
                    <div style="text-align: center; margin: 30px 0;">
                        <a href="%s" style="background-color: #28a745; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;">Börja handla nu</a>
                    </div>
                    <p>Tack för att du valde oss!</p>
                    <p>Med vänliga hälsningar,<br>CtrlBuy-teamet</p>
                </div>
            </body>
            </html>
            """.formatted(firstName, baseUrl);
    }

    private String createOrderConfirmationEmailHtml(String firstName, String orderNumber) {
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>Orderbekräftelse</title>
            </head>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h1 style="color: #007bff;">Tack för din beställning!</h1>
                    <p>Hej %s,</p>
                    <p>Vi har mottagit din beställning med ordernummer: <strong>%s</strong></p>
                    <p>Du kommer att få en uppdatering när din beställning skickas.</p>
                    <div style="text-align: center; margin: 30px 0;">
                        <a href="%s/orders" style="background-color: #007bff; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;">Se min beställning</a>
                    </div>
                    <p>Med vänliga hälsningar,<br>CtrlBuy-teamet</p>
                </div>
            </body>
            </html>
            """.formatted(firstName, orderNumber, baseUrl);
    }

    private String createDetailedOrderConfirmationEmailHtml(Order order) {
        StringBuilder itemsHtml = new StringBuilder();
        BigDecimal total = BigDecimal.ZERO;

        for (OrderItem item : order.getOrderItems()) {
            BigDecimal itemTotal = BigDecimal.valueOf(item.getPrice()).multiply(BigDecimal.valueOf(item.getQuantity()));
            total = total.add(itemTotal);

            itemsHtml.append("""
                <tr>
                    <td style="padding: 10px; border-bottom: 1px solid #eee;">%s</td>
                    <td style="padding: 10px; border-bottom: 1px solid #eee; text-align: center;">%d</td>
                    <td style="padding: 10px; border-bottom: 1px solid #eee; text-align: right;">%.2f kr</td>
                    <td style="padding: 10px; border-bottom: 1px solid #eee; text-align: right;">%.2f kr</td>
                </tr>
                """.formatted(item.getProductName(), item.getQuantity(), item.getPrice(), itemTotal.doubleValue()));
        }

        String orderDate = order.getOrderDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));

        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>Orderbekräftelse #%s</title>
            </head>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h1 style="color: #007bff;">Orderbekräftelse #%s</h1>
                    <p>Tack för din beställning! Här är detaljerna:</p>
                    
                    <div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
                        <h3>Orderinformation</h3>
                        <p><strong>Ordernummer:</strong> %s</p>
                        <p><strong>Orderdatum:</strong> %s</p>
                        <p><strong>Status:</strong> %s</p>
                    </div>

                    <h3>Beställda produkter</h3>
                    <table style="width: 100%%; border-collapse: collapse; margin: 20px 0;">
                        <thead>
                            <tr style="background-color: #007bff; color: white;">
                                <th style="padding: 10px; text-align: left;">Produkt</th>
                                <th style="padding: 10px; text-align: center;">Antal</th>
                                <th style="padding: 10px; text-align: right;">Pris</th>
                                <th style="padding: 10px; text-align: right;">Totalt</th>
                            </tr>
                        </thead>
                        <tbody>
                            %s
                            <tr style="background-color: #f8f9fa; font-weight: bold;">
                                <td colspan="3" style="padding: 15px; text-align: right;">Totalsumma:</td>
                                <td style="padding: 15px; text-align: right;">%.2f kr</td>
                            </tr>
                        </tbody>
                    </table>

                    <div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;">
                        <h3>Leveransadress</h3>
                        <p>%s<br>%s<br>%s %s</p>
                    </div>

                    <div style="text-align: center; margin: 30px 0;">
                        <a href="%s/orders" style="background-color: #007bff; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;">Se min beställning</a>
                    </div>
                    
                    <p>Du kommer att få en uppdatering när din beställning skickas.</p>
                    <p>Med vänliga hälsningar,<br>CtrlBuy-teamet</p>
                </div>
            </body>
            </html>
            """.formatted(
                order.getOrderNumber(), order.getOrderNumber(), order.getOrderNumber(),
                orderDate, order.getStatus().toString(), itemsHtml.toString(),
                total.doubleValue(), order.getDeliveryName(), order.getDeliveryAddress(),
                order.getDeliveryPostalCode(), order.getDeliveryCity(), baseUrl);
    }

    private String createAccountDeletionEmailHtml(String firstName, String adminUsername, String reason) {
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>Ditt konto har tagits bort</title>
            </head>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h1 style="color: #dc3545;">Ditt konto har tagits bort</h1>
                    <p>Hej %s,</p>
                    <p>Vi informerar dig om att ditt konto hos CtrlBuy har tagits bort av administratör: <strong>%s</strong></p>
                    %s
                    <p>Om du har frågor, kontakta vår kundtjänst.</p>
                    <p>Med vänliga hälsningar,<br>CtrlBuy-teamet</p>
                </div>
            </body>
            </html>
            """.formatted(firstName, adminUsername,
                reason != null && !reason.isEmpty() ? "<p><strong>Anledning:</strong> " + reason + "</p>" : "");
    }

    private String createAccountDeactivationEmailHtml(String firstName, String adminUsername, String reason) {
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>Ditt konto har deaktiverats</title>
            </head>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h1 style="color: #ffc107;">Ditt konto har deaktiverats</h1>
                    <p>Hej %s,</p>
                    <p>Vi informerar dig om att ditt konto hos CtrlBuy har deaktiverats av administratör: <strong>%s</strong></p>
                    %s
                    <p>För att aktivera ditt konto igen, kontakta vår kundtjänst.</p>
                    <p>Med vänliga hälsningar,<br>CtrlBuy-teamet</p>
                </div>
            </body>
            </html>
            """.formatted(firstName, adminUsername,
                reason != null && !reason.isEmpty() ? "<p><strong>Anledning:</strong> " + reason + "</p>" : "");
    }

    private String createAccountReactivationEmailHtml(String firstName, String adminUsername) {
        return """
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>Ditt konto har aktiverats</title>
            </head>
            <body style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
                <div style="max-width: 600px; margin: 0 auto; padding: 20px;">
                    <h1 style="color: #28a745;">Ditt konto har aktiverats! 🎉</h1>
                    <p>Hej %s,</p>
                    <p>Goda nyheter! Ditt konto hos CtrlBuy har aktiverats igen av administratör: <strong>%s</strong></p>
                    <p>Du kan nu logga in och fortsätta handla hos oss.</p>
                    <div style="text-align: center; margin: 30px 0;">
                        <a href="%s/login" style="background-color: #28a745; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;">Logga in</a>
                    </div>
                    <p>Med vänliga hälsningar,<br>CtrlBuy-teamet</p>
                </div>
            </body>
            </html>
            """.formatted(firstName, adminUsername, baseUrl);
    }
}