package com.saas.voip.handler;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.saas.admin.service.PhoneNumberService;
import com.saas.voip.service.OpenAIRealtimeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.util.HashMap;
import java.util.Map;

@Component
@RequiredArgsConstructor
@Slf4j
public class OpenAiSessionHandler implements AiSessionHandler {
    
    private final OpenAIRealtimeService openAIRealtimeService;
    private final PhoneNumberService phoneNumberService;
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public void onClientConnect(WebSocketSession session, String streamSid, String callSid, String fromNumber, String toNumber) throws Exception {
        log.info("OpenAI handler - Client connected: streamSid={}, callSid={}, from={}, to={}", 
                streamSid, callSid, fromNumber, toNumber);
        
        openAIRealtimeService.setStreamSid(session.getId(), streamSid);
        openAIRealtimeService.setCallSidForSession(session.getId(), callSid);
        openAIRealtimeService.connectToOpenAI(session);
        
        // Resolve tenantId from phone number for AI cost tracking
        String tenantId = null;
        if (toNumber != null) {
            tenantId = phoneNumberService.getTenantIdByPhoneNumber(toNumber).orElse(null);
            if (tenantId != null) {
                log.info("💰 [CostTracking] Resolved tenantId '{}' from phone number: {}", tenantId, toNumber);
            } else {
                log.warn("⚠️ [CostTracking] Could not resolve tenantId for phone number: {}, using default", toNumber);
                tenantId = "default_tenant";
            }
        } else {
            log.warn("⚠️ [CostTracking] No toNumber provided, using default tenantId");
            tenantId = "default_tenant";
        }
        
        // Set call metadata for AI cost tracking
        openAIRealtimeService.setCallMetadata(session.getId(), tenantId, fromNumber, toNumber);
    }
    
    @Override
    public void onMediaFrame(WebSocketSession session, String payload) throws Exception {
        JsonNode mediaNode = objectMapper.readTree(payload);
        if (mediaNode.has("media") && mediaNode.get("media").has("payload")) {
            String audioPayload = mediaNode.get("media").get("payload").asText();
            openAIRealtimeService.sendAudioToOpenAI(session, audioPayload);
        }
    }
    
    @Override
    public void onMark(WebSocketSession session, Map<String, Object> markData) throws Exception {
        // No special handling needed for OpenAI
        log.debug("Mark event received (no action required for OpenAI)");
    }
    
    @Override
    public void onClose(WebSocketSession session) throws Exception {
        log.info("OpenAI handler - Closing session: {}", session.getId());
        openAIRealtimeService.closeConnection(session);
    }
    
    @Override
    public boolean supportsStructuredExtraction() {
        return true; // OpenAI uses function calling for structured extraction
    }
    
    @Override
    public Map<String, Object> buildStructuredPayload(String transcript) {
        // OpenAI handles this via function calling internally
        return new HashMap<>();
    }
}
