import logging
from typing import Literal, Optional

from connexity.client import ConnexityClient
from pipecat.audio.vad.vad_analyzer import VADParams
from twilio.rest import Client

from connexity.metrics.pipecat_interface import InterfaceConnexityObserver

from connexity.metrics.utils.get_daily_recording_url import get_daily_recording_url

logger = logging.getLogger(__name__)


class ConnexityDailyObserver(InterfaceConnexityObserver):

    async def initialize(self,
                         sid: str,
                         agent_id: str,
                         api_key: str,
                         call_type: Literal["inbound", "outbound", "web"],
                         vad_params: VADParams,
                         env: Literal["development", "production"],
                         vad_analyzer: str,
                         phone_call_provider: str = None,
                         user_phone_number: str = None,
                         agent_phone_number: str = None,
                         twilio_client: Client = None,
                         daily_api_key: str = None,
                         verbose: bool = False,
                         latency_threshold_ms: Optional[float] = 4000.0
                         ):
        try:
            if not daily_api_key:
                raise ValueError("DAILY API KEY NOT PROVIDED")
            
            self._verbose = verbose
            self.vad_stop_secs = vad_params.stop_secs
            self.vad_start_secs = vad_params.start_secs
            self.sid = sid
            self.daily_api_key = daily_api_key
            self.latency_threshold_ms = latency_threshold_ms
            connexity_client = ConnexityClient(api_key=api_key)
            self.call = await connexity_client.register_call(
                sid=sid,
                agent_id=agent_id,
                user_phone_number=user_phone_number,
                agent_phone_number=agent_phone_number,
                created_at=None,
                voice_engine='daily',
                call_type="web",
                phone_call_provider=phone_call_provider,
                stream=False,
                env=env,
                vad_analyzer=vad_analyzer
            )
            
            self._initialized = True
            logger.info("Connexity SDK: Observer initialized successfully")
            
        except TypeError as e:
            self._initialization_failed = True
            logger.error(
                f"Connexity SDK: Initialization failed due to type error: {e}. "
                "Observer will be disabled. Customer's agent will continue without observability.",
                exc_info=True
            )
        except ValueError as e:
            self._initialization_failed = True
            logger.error(
                f"Connexity SDK: Initialization failed due to invalid parameters: {e}. "
                "Observer will be disabled. Customer's agent will continue without observability.",
                exc_info=True
            )
        except Exception as e:
            self._initialization_failed = True
            logger.error(
                f"Connexity SDK: Initialization failed unexpectedly: {type(e).__name__}: {e}. "
                "Observer will be disabled. Customer's agent will continue without observability.",
                exc_info=True
            )

    async def post_process_data(self):
        if self._initialization_failed or not self._initialized:
            return
        
        try:
            recording_url, duration = get_daily_recording_url(self.daily_api_key, self.sid)

            await self.call.init_post_call_data(
                recording_url=recording_url,
                created_at=None,
                duration_in_seconds=duration
            )
        except Exception as e:
            logger.error(f"Connexity SDK: Error in post_process_data (Daily): {e}", exc_info=True)
