package com.saas.voip.service;

import com.saas.shared.enums.AIProvider;
import com.saas.admin.entity.TenantAIConfig;
import com.saas.tenant.service.TenantAIConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalTime;
import java.util.Optional;

/**
 * Twilio Call Bridge Service
 * 
 * Generates TwiML to bridge Twilio calls to AI assistants (Vapi or Retell)
 * 
 * Unlike Telnyx (which uses Call Control API), Twilio uses TwiML responses
 * to control call flow directly in the webhook response.
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class TwilioCallBridgeService {

    private final TenantAIConfigService aiConfigService;

    /**
     * Generate TwiML to bridge call to AI assistant
     * 
     * @param tenantId   Tenant identifier
     * @param fromNumber Caller phone number
     * @param toNumber   Called phone number (tenant's number)
     * @param callSid    Twilio Call SID
     * @return TwiML XML string
     */
    public String generateBridgeTwiML(
            String tenantId,
            String fromNumber,
            String toNumber,
            String callSid) {
        log.info("🔗 Generating TwiML to bridge Twilio call {} for tenant: {}", callSid, tenantId);

        try {
            // Get AI configuration
            AIProvider provider = aiConfigService.resolveProvider(tenantId, LocalTime.now());

            log.info("🎯 Resolved AI provider: {}", provider);

            // Generate TwiML based on provider
            return switch (provider) {
                case RETELL -> generateRetellTwiML(tenantId, fromNumber, toNumber);
                case VAPI -> generateVapiTwiML(tenantId, fromNumber, toNumber);
                case NONE -> generateNoAITwiML();
                default -> generateErrorTwiML();
            };

        } catch (Exception e) {
            log.error("❌ Error generating bridge TwiML", e);
            return generateErrorTwiML();
        }
    }

    /**
     * Generate TwiML to dial Retell phone number
     */
    private String generateRetellTwiML(String tenantId, String fromNumber, String toNumber) {
        Optional<TenantAIConfig> configOpt = aiConfigService.getConfigForTenant(tenantId);

        if (configOpt.isEmpty() || configOpt.get().getRetellPhoneNumber() == null) {
            log.warn("⚠️ No Retell phone number configured for tenant: {}", tenantId);
            return generateNoAITwiML();
        }

        String retellPhoneNumber = configOpt.get().getRetellPhoneNumber();

        log.info("📞 Dialing Retell phone number: {}", retellPhoneNumber);

        // TwiML to dial Retell's phone number
        return """
                <?xml version="1.0" encoding="UTF-8"?>
                <Response>
                    <Say voice="Polly.Lea" language="fr-FR">
                        Connexion à votre assistant virtuel, veuillez patienter.
                    </Say>
                    <Dial>%s</Dial>
                </Response>
                """.formatted(retellPhoneNumber);
    }

    /**
     * Generate TwiML to dial Vapi phone number
     */
    private String generateVapiTwiML(String tenantId, String fromNumber, String toNumber) {
        Optional<TenantAIConfig> configOpt = aiConfigService.getConfigForTenant(tenantId);

        if (configOpt.isEmpty() || configOpt.get().getVapiPhoneNumber() == null) {
            log.warn("⚠️ No Vapi phone number configured for tenant: {}", tenantId);
            return generateNoAITwiML();
        }

        String vapiPhoneNumber = configOpt.get().getVapiPhoneNumber();

        log.info("📞 Dialing Vapi phone number: {}", vapiPhoneNumber);

        // TwiML to dial Vapi's phone number
        return """
                <?xml version="1.0" encoding="UTF-8"?>
                <Response>
                    <Say voice="Polly.Lea" language="fr-FR">
                        Connexion à votre assistant virtuel, veuillez patienter.
                    </Say>
                    <Dial>%s</Dial>
                </Response>
                """.formatted(vapiPhoneNumber);
    }

    /**
     * Generate TwiML for SIP dial (alternative method)
     * 
     * This can be used if Retell/Vapi provide SIP URIs instead of phone numbers
     */
    private String generateSipDialTwiML(String sipUri, String provider) {
        log.info("📞 Dialing SIP URI for {}: {}", provider, sipUri);

        return """
                <?xml version="1.0" encoding="UTF-8"?>
                <Response>
                    <Say voice="Polly.Lea" language="fr-FR">
                        Connexion à votre assistant virtuel, veuillez patienter.
                    </Say>
                    <Dial>
                        <Sip>%s</Sip>
                    </Dial>
                </Response>
                """.formatted(sipUri);
    }

    /**
     * Generate TwiML when no AI is configured
     */
    private String generateNoAITwiML() {
        log.warn("⚠️ No AI configured - returning error message");

        return """
                <?xml version="1.0" encoding="UTF-8"?>
                <Response>
                    <Say voice="Polly.Lea" language="fr-FR">
                        Désolé, ce service n'est pas disponible pour le moment. Veuillez réessayer plus tard.
                    </Say>
                    <Hangup/>
                </Response>
                """;
    }

    /**
     * Generate TwiML for errors
     */
    private String generateErrorTwiML() {
        log.error("❌ Error generating TwiML - returning error message");

        return """
                <?xml version="1.0" encoding="UTF-8"?>
                <Response>
                    <Say voice="Polly.Lea" language="fr-FR">
                        Nous rencontrons un problème technique. Veuillez réessayer dans quelques instants.
                    </Say>
                    <Hangup/>
                </Response>
                """;
    }

    /**
     * Generate TwiML with custom message
     */
    public String generateCustomMessageTwiML(String message, String voice, String language) {
        return """
                <?xml version="1.0" encoding="UTF-8"?>
                <Response>
                    <Say voice="%s" language="%s">%s</Say>
                    <Hangup/>
                </Response>
                """.formatted(voice, language, message);
    }
}
