package com.saas.voip.extractor;

import com.saas.tenant.entity.InboundCallData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * Extractor for Twilio webhook data
 * Similar to TelnyxCallDataExtractor but adapted for Twilio's form-encoded format
 */
@Component
@Slf4j
public class TwilioCallDataExtractor {

    private static final DateTimeFormatter TWILIO_DATE_FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss Z");

    /**
     * Extract InboundCallData from Twilio webhook form data
     */
    public InboundCallData extractFromTwilioRequest(MultiValueMap<String, String> formData) {
        try {
            InboundCallData callData = new InboundCallData();
            
            // Basic call info
            callData.setCallSid(getString(formData, "CallSid"));
            callData.setProvider("TWILIO");
            callData.setFromNumber(getString(formData, "From"));
            callData.setToNumber(getString(formData, "To"));
            callData.setCallStatus(getString(formData, "CallStatus"));
            callData.setDirection(getString(formData, "Direction", "inbound"));
            
            // Twilio-specific identifiers
            callData.setAccountSid(getString(formData, "AccountSid"));
            callData.setApiVersion(getString(formData, "ApiVersion"));
            callData.setCallToken(getString(formData, "CallToken"));
            callData.setParentCallSid(getString(formData, "ParentCallSid"));
            
            // Caller info (From)
            callData.setFromCity(getString(formData, "FromCity"));
            callData.setFromState(getString(formData, "FromState"));
            callData.setFromCountry(getString(formData, "FromCountry"));
            callData.setFromZip(getString(formData, "FromZip"));
            
            // Called info (To)
            callData.setToCity(getString(formData, "ToCity"));
            callData.setToState(getString(formData, "ToState"));
            callData.setToCountry(getString(formData, "ToCountry"));
            callData.setToZip(getString(formData, "ToZip"));
            
            // Alternative caller/called format
            callData.setCaller(getString(formData, "Caller"));
            callData.setCallerCity(getString(formData, "CallerCity"));
            callData.setCallerState(getString(formData, "CallerState"));
            callData.setCallerCountry(getString(formData, "CallerCountry"));
            callData.setCallerZip(getString(formData, "CallerZip"));
            
            callData.setCalled(getString(formData, "Called"));
            callData.setCalledCity(getString(formData, "CalledCity"));
            callData.setCalledState(getString(formData, "CalledState"));
            callData.setCalledCountry(getString(formData, "CalledCountry"));
            callData.setCalledZip(getString(formData, "CalledZip"));
            
            // Additional metadata
            callData.setForwardedFrom(getString(formData, "ForwardedFrom"));
            callData.setStirVerstat(getString(formData, "StirVerstat"));
            
            // Timestamps - set start time to now for incoming call
            callData.setStartTime(LocalDateTime.now());
            
            log.debug("📊 Extracted call data from Twilio - CallSid: {}", callData.getCallSid());
            
            return callData;
            
        } catch (Exception e) {
            log.error("Error extracting Twilio call data", e);
            throw new RuntimeException("Failed to extract Twilio call data", e);
        }
    }
    
    private String getString(MultiValueMap<String, String> formData, String key) {
        return getString(formData, key, null);
    }
    
    private String getString(MultiValueMap<String, String> formData, String key, String defaultValue) {
        if (formData == null || !formData.containsKey(key)) {
            return defaultValue;
        }
        String value = formData.getFirst(key);
        return (value != null && !value.isEmpty()) ? value : defaultValue;
    }
}
