package com.devjob.notification.service;

import com.devjob.notification.domain.Notification;
import com.devjob.notification.repository.NotificationRepository;
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.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * EP09: 시즌1 EmailService를 독립 서비스로 확장.
 * - 발송 시도마다 Notification 레코드를 PENDING으로 먼저 저장하고,
 *   실제 발송 결과(SENT/FAILED)를 비동기로 갱신한다.
 * - mail.enabled=false(기본값, 로컬 개발용)일 때는 실제 발송 대신 로그만 남기고 SENT 처리한다.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EmailService {

    private final JavaMailSender mailSender;
    private final NotificationRepository notificationRepository;

    @Value("${mail.enabled:false}")
    private boolean mailEnabled;

    @Transactional
    public Notification send(Long userId, String to, String subject, String content) {
        Notification notification = Notification.builder()
                .userId(userId)
                .recipientEmail(to)
                .subject(subject)
                .content(content)
                .build();
        Notification saved = notificationRepository.save(notification);
        sendAsync(saved.getId(), to, subject, content);
        return saved;
    }

    @Async
    @Transactional
    public void sendAsync(Long notificationId, String to, String subject, String content) {
        Notification notification = notificationRepository.findById(notificationId).orElseThrow();

        if (!mailEnabled) {
            log.info("[메일 발송 생략] to={}, subject={}", to, subject);
            notification.markSent();
            return;
        }

        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            mailSender.send(message);
            notification.markSent();
            log.info("메일 발송 성공: to={}", to);
        } catch (MessagingException e) {
            notification.markFailed();
            log.error("메일 발송 실패: to={}", to, e);
        }
    }
}
