package com.unicorn.hgzero.notification.service;

import jakarta.mail.MessagingException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 이메일 알림 발송 서비스
 *
 * 템플릿 로드, 렌더링, 이메일 발송 통합 처리
 * 재시도 로직 포함
 *
 * @author 준호 (Backend Developer)
 * @version 1.0
 * @since 2025-10-25
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class EmailNotifier {

    private final EmailTemplateService templateService;
    private final EmailClient emailClient;
    private final RetryTemplate retryTemplate;

    /**
     * 이메일 발송 (재시도 지원)
     *
     * @param recipientEmail 수신자 이메일
     * @param subject 이메일 제목
     * @param htmlContent 이메일 HTML 본문
     * @return 발송 성공 여부
     */
    public boolean sendEmail(String recipientEmail, String subject, String htmlContent) {
        try {
            return retryTemplate.execute(context -> {
                try {
                    log.info("이메일 발송 시도 #{} - Email: {}", context.getRetryCount() + 1, recipientEmail);

                    emailClient.sendHtmlEmail(recipientEmail, subject, htmlContent);

                    log.info("이메일 발송 성공 - Email: {}", recipientEmail);
                    return true;

                } catch (MessagingException e) {
                    log.error("이메일 발송 실패 (재시도 #{}) - Email: {}",
                        context.getRetryCount() + 1, recipientEmail, e);

                    if (context.getRetryCount() >= 2) {
                        log.error("최대 재시도 횟수 초과 - Email: {}", recipientEmail);
                        return false;
                    }

                    throw new RuntimeException("이메일 발송 실패", e);
                }
            });

        } catch (Exception e) {
            log.error("이메일 발송 최종 실패 - Email: {}", recipientEmail, e);
            return false;
        }
    }

    /**
     * 템플릿 기반 이메일 발송
     *
     * 템플릿을 로드하고 데이터를 렌더링하여 이메일 발송
     *
     * @param recipientEmail 수신자 이메일
     * @param subject 이메일 제목
     * @param templateId 템플릿 ID
     * @param templateData 템플릿 데이터
     * @return 발송 성공 여부
     */
    public boolean sendTemplateEmail(
        String recipientEmail,
        String subject,
        String templateId,
        Map<String, Object> templateData
    ) {
        try {
            log.info("템플릿 이메일 발송 시작 - Template: {}, Email: {}", templateId, recipientEmail);

            // 템플릿 로드 및 렌더링
            String htmlContent = loadAndRenderTemplate(templateId, templateData);

            // 이메일 발송
            return sendEmail(recipientEmail, subject, htmlContent);

        } catch (Exception e) {
            log.error("템플릿 이메일 발송 실패 - Template: {}, Email: {}", templateId, recipientEmail, e);
            return false;
        }
    }

    /**
     * 템플릿 로드 및 렌더링
     *
     * @param templateId 템플릿 ID
     * @param templateData 템플릿 데이터
     * @return 렌더링된 HTML 본문
     */
    public String loadAndRenderTemplate(String templateId, Map<String, Object> templateData) {
        log.info("템플릿 로드 중 - TemplateId: {}", templateId);

        String htmlContent;

        switch (templateId) {
            case "meeting-invitation":
                htmlContent = templateService.renderMeetingInvitation(templateData);
                break;

            case "todo-assigned":
                htmlContent = templateService.renderTodoAssigned(templateData);
                break;

            case "meeting-reminder":
                // 향후 구현
                log.warn("회의 알림 템플릿은 아직 구현되지 않았습니다");
                htmlContent = renderDefaultTemplate(templateData);
                break;

            case "todo-reminder":
                // 향후 구현
                log.warn("Todo 알림 템플릿은 아직 구현되지 않았습니다");
                htmlContent = renderDefaultTemplate(templateData);
                break;

            case "minutes-updated":
                // 향후 구현
                log.warn("회의록 수정 템플릿은 아직 구현되지 않았습니다");
                htmlContent = renderDefaultTemplate(templateData);
                break;

            default:
                log.warn("알 수 없는 템플릿 ID: {} - 기본 템플릿 사용", templateId);
                htmlContent = renderDefaultTemplate(templateData);
                break;
        }

        log.info("템플릿 렌더링 완료 - TemplateId: {}", templateId);
        return htmlContent;
    }

    /**
     * 기본 템플릿 렌더링
     *
     * @param templateData 템플릿 데이터
     * @return 렌더링된 HTML 본문
     */
    private String renderDefaultTemplate(Map<String, Object> templateData) {
        String title = (String) templateData.getOrDefault("title", "알림");
        String message = (String) templateData.getOrDefault("message", "");

        return String.format("""
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <title>%s</title>
            </head>
            <body>
                <h2>%s</h2>
                <p>%s</p>
            </body>
            </html>
            """, title, title, message);
    }
}
