"""
Voice client implementation for STT and TTS usage tracking.
"""

import logging
from typing import Dict
from urllib.parse import urljoin

import requests

from .constants import (
    DeepgramSTTModels,
    MicrosoftAzureSpeechSTTModels,
    GoogleCloudSpeechSTTModels,
    AssemblyAISTTModels,
    ElevenLabsSTTModels,
    SonioxSTTModels,
    AmazonPollyTTSModels,
    MicrosoftAzureSpeechTTSModels,
    GoogleCloudTextToSpeechTTSModels,
    DeepgramTTSModels,
    ElevenLabsTTSModels,
)
from .models import RawUsageData


def send_stt_usage(client_instance, agent_id: str, customer_id: str, stt_usage_data) -> None:
    """
    Send STT usage data to the Paygent API using V2 endpoint.
    
    Args:
        client_instance: The Client instance
        agent_id: Unique identifier for the agent
        customer_id: Unique identifier for the customer
        stt_usage_data: SttUsageData containing model and audio duration information
        
    Raises:
        requests.RequestException: If the request fails
    """
    client_instance.logger.debug(f"Sending STT usage data for model: {stt_usage_data.model}")
    
    try:
        from .models import RawUsageData
        
        # Use V2 usage tracking for server-side pricing
        raw_usage = RawUsageData(
            provider=stt_usage_data.service_provider,
            model=stt_usage_data.model,
            audio_duration=stt_usage_data.audio_duration,
            plan=stt_usage_data.plan
        )
        
        client_instance.send_usage_v2(agent_id, customer_id, 'stt-usage', raw_usage)
        client_instance.logger.info('STT usage data sent successfully')
        
    except Exception as e:
        client_instance.logger.error(f"Failed to send STT usage data: {str(e)}")
        raise


def send_tts_usage(client_instance, agent_id: str, customer_id: str, tts_usage_data) -> None:
    """
    Send TTS usage data to the Paygent API using V2 endpoint.
    
    Args:
        client_instance: The Client instance
        agent_id: Unique identifier for the agent
        customer_id: Unique identifier for the customer
        tts_usage_data: TtsUsageData containing model and character count information
        
    Raises:
        requests.RequestException: If the request fails
    """
    client_instance.logger.debug(f"Sending TTS usage data for model: {tts_usage_data.model}")
    
    try:
        from .models import RawUsageData
        
        # Use V2 usage tracking for server-side pricing
        raw_usage = RawUsageData(
            provider=tts_usage_data.service_provider,
            model=tts_usage_data.model,
            character_count=tts_usage_data.character_count,
            plan=tts_usage_data.plan
        )
        
        client_instance.send_usage_v2(agent_id, customer_id, 'tts-usage', raw_usage)
        client_instance.logger.info('TTS usage data sent successfully')
        
    except Exception as e:
        client_instance.logger.error(f"Failed to send TTS usage data: {str(e)}")
        raise


def initialize_voice_session(client_instance, session_id: str, agent_id: str, customer_id: str) -> None:
    """
    Initialize a new voice session.
    
    Args:
        client_instance: The Client instance
        session_id: Unique identifier for the session
        agent_id: Unique identifier for the agent
        customer_id: Unique identifier for the customer
        
    Raises:
        requests.RequestException: If the request fails
    """
    client_instance.logger.debug(f"Initializing voice session: {session_id}")
    
    try:
        url = urljoin(client_instance.base_url, "/api/v1/voice/session")
        headers = {
            "Content-Type": "application/json",
            "paygent-api-key": client_instance.api_key,
        }
        
        request_data = {
            "sessionId": session_id,
            "agentId": agent_id,
            "customerId": customer_id,
        }
        
        response = client_instance.session.post(url, json=request_data, headers=headers)
        response.raise_for_status()
        
        client_instance.logger.info("Voice session initialized successfully")
    except requests.RequestException as e:
        client_instance.logger.error(f"Failed to initialize voice session: {str(e)}")
        raise


def track_voice_stt(
    client_instance,
    session_id: str,
    stt_usage_data: dict
) -> None:
    """
    Track STT usage for a voice session.
    
    Args:
        client_instance: The Client instance
        session_id: Unique identifier for the session
        stt_usage_data: Dict containing audioDuration, serviceProvider, model, and optional language
        
    Raises:
        requests.RequestException: If the request fails
    """
    client_instance.logger.debug(f"Tracking voice STT usage for session: {session_id}")
    
    try:
        url = urljoin(client_instance.base_url, "/api/v1/voice/stt")
        headers = {
            "Content-Type": "application/json",
            "paygent-api-key": client_instance.api_key,
        }
        
        request_data = {
            "sessionId": session_id,
            "audioMinutes": stt_usage_data.get("audioDuration"),
            "provider": stt_usage_data.get("serviceProvider"),
            "model": stt_usage_data.get("model"),
            "plan": stt_usage_data.get("plan"),
        }
        
        # Add optional language field
        if "language" in stt_usage_data:
            request_data["language"] = stt_usage_data["language"]
        
        response = client_instance.session.post(url, json=request_data, headers=headers)
        response.raise_for_status()
        
        client_instance.logger.info("Voice STT usage tracked successfully")
    except requests.RequestException as e:
        client_instance.logger.error(f"Failed to track voice STT: {str(e)}")
        raise


def track_voice_llm(
    client_instance,
    session_id: str,
    llm_usage_data: dict
) -> None:
    """
    Track LLM usage for a voice session.
    
    Args:
        client_instance: The Client instance
        session_id: Unique identifier for the session
        llm_usage_data: Dict containing serviceProvider, model, promptTokens, completionTokens
        
    Raises:
        requests.RequestException: If the request fails
    """
    client_instance.logger.debug(f"Tracking voice LLM usage for session: {session_id}")
    
    try:
        url = urljoin(client_instance.base_url, "/api/v1/voice/llm")
        headers = {
            "Content-Type": "application/json",
            "paygent-api-key": client_instance.api_key,
        }
        
        request_data = {
            "sessionId": session_id,
            "provider": llm_usage_data.get("serviceProvider"),
            "model": llm_usage_data.get("model"),
            "plan": llm_usage_data.get("plan"),
            "promptTokens": llm_usage_data.get("promptTokens"),
            "completionTokens": llm_usage_data.get("completionTokens"),
        }
        
        response = client_instance.session.post(url, json=request_data, headers=headers)
        response.raise_for_status()
        
        client_instance.logger.info("Voice LLM usage tracked successfully")
    except requests.RequestException as e:
        client_instance.logger.error(f"Failed to track voice LLM: {str(e)}")
        raise


def track_voice_tts(
    client_instance,
    session_id: str,
    tts_usage_data: dict
) -> None:
    """
    Track TTS usage for a voice session.
    
    Args:
        client_instance: The Client instance
        session_id: Unique identifier for the session
        tts_usage_data: Dict containing serviceProvider, model, characterCount
        
    Raises:
        requests.RequestException: If the request fails
    """
    client_instance.logger.debug(f"Tracking voice TTS usage for session: {session_id}")
    
    try:
        url = urljoin(client_instance.base_url, "/api/v1/voice/tts")
        headers = {
            "Content-Type": "application/json",
            "paygent-api-key": client_instance.api_key,
        }
        
        request_data = {
            "sessionId": session_id,
            "provider": tts_usage_data.get("serviceProvider"),
            "model": tts_usage_data.get("model"),
            "plan": tts_usage_data.get("plan"),
            "characters": tts_usage_data.get("characterCount"),
        }
        
        response = client_instance.session.post(url, json=request_data, headers=headers)
        response.raise_for_status()
        
        client_instance.logger.info("Voice TTS usage tracked successfully")
    except requests.RequestException as e:
        client_instance.logger.error(f"Failed to track voice TTS: {str(e)}")
        raise


def set_voice_indicator(
    client_instance,
    session_id: str,
    indicator: str,
    total_duration: int
) -> None:
    """
    Set an indicator for a voice session with final duration.
    
    Args:
        client_instance: The Client instance
        session_id: Unique identifier for the session
        indicator: Indicator for the session
        total_duration: Total duration of the session in seconds
        
    Raises:
        requests.RequestException: If the request fails
    """
    client_instance.logger.debug(f"Setting voice indicator: {indicator} for session: {session_id}")
    
    try:
        url = urljoin(client_instance.base_url, "/api/v1/voice/indicator")
        headers = {
            "Content-Type": "application/json",
            "paygent-api-key": client_instance.api_key,
        }
        
        request_data = {
            "sessionId": session_id,
            "indicator": indicator,
            "totalDuration": total_duration,
        }
        
        response = client_instance.session.post(url, json=request_data, headers=headers)
        response.raise_for_status()
        
        client_instance.logger.info("Voice indicator set successfully")
    except requests.RequestException as e:
        client_instance.logger.error(f"Failed to set voice indicator: {str(e)}")
        raise


# Add methods to Client class
def _add_voice_methods_to_client():
    """Dynamically add voice methods to the Client class."""
    from .client import Client
    
    Client.send_stt_usage = send_stt_usage
    Client.send_tts_usage = send_tts_usage
    Client.initialize_voice_session = initialize_voice_session
    Client.track_voice_stt = track_voice_stt
    Client.track_voice_llm = track_voice_llm
    Client.track_voice_tts = track_voice_tts
    Client.set_voice_indicator = set_voice_indicator


# Call this function to attach methods when module is imported
_add_voice_methods_to_client()

