package com.unicorn.hgzero.user.service;

import com.azure.messaging.eventhubs.EventData;
import com.azure.messaging.eventhubs.EventHubProducerClient;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.HashMap;
import java.util.Map;

/**
 * 이벤트 발행 서비스 구현체
 * Azure EventHub를 통한 사용자 인증 이벤트 발행
 */
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnBean(EventHubProducerClient.class)
public class EventPublishServiceImpl implements EventPublishService {

    private final EventHubProducerClient eventHubProducerClient;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void publishLoginEvent(String userId, String username, long timestamp) {
        Map<String, Object> eventData = new HashMap<>();
        eventData.put("eventType", "USER_LOGIN");
        eventData.put("userId", userId);
        eventData.put("username", username);
        eventData.put("timestamp", timestamp);
        eventData.put("eventTime", Instant.ofEpochMilli(timestamp).toString());
        
        publishEvent(eventData, "로그인 이벤트");
    }

    @Override
    public void publishLogoutEvent(String userId, long timestamp) {
        Map<String, Object> eventData = new HashMap<>();
        eventData.put("eventType", "USER_LOGOUT");
        eventData.put("userId", userId);
        eventData.put("timestamp", timestamp);
        eventData.put("eventTime", Instant.ofEpochMilli(timestamp).toString());
        
        publishEvent(eventData, "로그아웃 이벤트");
    }

    @Override
    public void publishTokenRefreshEvent(String userId, long timestamp) {
        Map<String, Object> eventData = new HashMap<>();
        eventData.put("eventType", "TOKEN_REFRESH");
        eventData.put("userId", userId);
        eventData.put("timestamp", timestamp);
        eventData.put("eventTime", Instant.ofEpochMilli(timestamp).toString());
        
        publishEvent(eventData, "토큰 갱신 이벤트");
    }

    /**
     * EventHub로 이벤트 발행
     * 
     * @param eventData 이벤트 데이터
     * @param eventDescription 이벤트 설명 (로깅용)
     */
    private void publishEvent(Map<String, Object> eventData, String eventDescription) {
        if (eventHubProducerClient == null) {
            log.debug("EventHub Producer Client가 없어 {} 발행을 건너뜀", eventDescription);
            return;
        }

        try {
            String jsonData = objectMapper.writeValueAsString(eventData);
            EventData event = new EventData(jsonData);
            
            // EventData를 Iterable로 감싸서 전송
            eventHubProducerClient.send(java.util.Collections.singletonList(event));
            log.debug("{} 발행 완료: {}", eventDescription, eventData.get("userId"));
            
        } catch (JsonProcessingException e) {
            log.error("{} JSON 변환 실패: {}", eventDescription, e.getMessage());
        } catch (Exception e) {
            log.error("{} 발행 실패: {}", eventDescription, e.getMessage());
        }
    }
}