package com.unicorn.hgzero.notification.service;

import com.unicorn.hgzero.notification.domain.Notification;
import com.unicorn.hgzero.notification.domain.NotificationSetting;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 알림 채널 라우팅 서비스
 *
 * 사용자 설정에 따라 적절한 알림 채널을 결정
 * 이메일 우선, SMS 백업 전략 사용
 *
 * @author 준호 (Backend Developer)
 * @version 1.0
 * @since 2025-10-25
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class NotificationRouter {

    private final EmailNotifier emailNotifier;

    /**
     * 알림 라우팅 및 발송
     *
     * @param eventId 이벤트 ID
     * @param recipientEmail 수신자 이메일
     * @param recipientName 수신자 이름
     * @param subject 이메일 제목
     * @param htmlContent 이메일 HTML 본문
     * @param preferences 사용자 알림 설정
     * @param requestedChannel 요청된 채널
     * @return 발송 성공 여부
     */
    public boolean routeNotification(
        String eventId,
        String recipientEmail,
        String recipientName,
        String subject,
        String htmlContent,
        NotificationSetting preferences,
        Notification.NotificationChannel requestedChannel
    ) {
        log.info("알림 라우팅 시작 - Email: {}, Channel: {}", recipientEmail, requestedChannel);

        // 채널 결정
        Notification.NotificationChannel selectedChannel = determineChannel(preferences, requestedChannel);

        log.info("선택된 채널: {}", selectedChannel);

        // 채널별 발송
        boolean success = false;

        switch (selectedChannel) {
            case EMAIL:
                success = emailNotifier.sendEmail(recipientEmail, subject, htmlContent);
                break;

            case SMS:
                // SMS 발송 로직 (향후 구현)
                log.warn("SMS 채널은 아직 구현되지 않았습니다. 이메일로 대체 발송 시도");
                success = emailNotifier.sendEmail(recipientEmail, subject, htmlContent);
                break;

            case PUSH:
                // PUSH 알림 로직 (향후 구현)
                log.warn("PUSH 채널은 아직 구현되지 않았습니다. 이메일로 대체 발송 시도");
                success = emailNotifier.sendEmail(recipientEmail, subject, htmlContent);
                break;

            default:
                log.error("알 수 없는 채널: {}", selectedChannel);
                break;
        }

        if (success) {
            log.info("알림 발송 성공 - Email: {}, Channel: {}", recipientEmail, selectedChannel);
        } else {
            log.error("알림 발송 실패 - Email: {}, Channel: {}", recipientEmail, selectedChannel);
        }

        return success;
    }

    /**
     * 채널 결정 로직
     *
     * 사용자 설정과 요청 채널을 고려하여 최종 채널 결정
     * 이메일 우선, SMS 백업 전략
     *
     * @param preferences 사용자 알림 설정
     * @param requestedChannel 요청된 채널
     * @return 선택된 채널
     */
    private Notification.NotificationChannel determineChannel(
        NotificationSetting preferences,
        Notification.NotificationChannel requestedChannel
    ) {
        // 사용자 설정이 없으면 요청된 채널 사용
        if (preferences == null) {
            log.info("사용자 설정 없음 - 요청 채널 사용: {}", requestedChannel);
            return requestedChannel != null ? requestedChannel : Notification.NotificationChannel.EMAIL;
        }

        // 이메일 우선 전략
        if (requestedChannel == Notification.NotificationChannel.EMAIL && preferences.isChannelEnabled(Notification.NotificationChannel.EMAIL)) {
            return Notification.NotificationChannel.EMAIL;
        }

        // SMS 백업 전략
        if (requestedChannel == Notification.NotificationChannel.SMS && preferences.isChannelEnabled(Notification.NotificationChannel.SMS)) {
            return Notification.NotificationChannel.SMS;
        }

        // PUSH 알림 전략
        if (requestedChannel == Notification.NotificationChannel.PUSH && preferences.isChannelEnabled(Notification.NotificationChannel.PUSH)) {
            return Notification.NotificationChannel.PUSH;
        }

        // 기본값: 이메일
        log.info("요청된 채널 사용 불가 - 기본 이메일 채널 사용");
        return Notification.NotificationChannel.EMAIL;
    }
}
