import typing
from ...core.client_wrapper import SyncClientWrapper, AsyncClientWrapper
from .connection import ListenConnection, AsyncListenConnection

ENCODING_TYPES = typing.Literal["linear16", "linear32", "mulaw", "alaw"]

class ListenV1Client:
    def __init__(self, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def connect(
        self,
        *,
        sample_rate: int,
        channels: int,
        encoding: ENCODING_TYPES,
        language: str = "en-us",
        translate_to_language: typing.Optional[str] = None,
        punctuate: bool = True,
        diarize: bool = False,
        interim_results: bool = True,
        model: str = "camb",
    ) -> ListenConnection:
        params = {
            "model": model,
            "language": language,
            "sample_rate": sample_rate,
            "channels": channels,
            "punctuate": str(punctuate).lower(),
            "diarize": str(diarize).lower(),
            "interim_results": str(interim_results).lower(),
        }
        if translate_to_language:
            params["translate_to_language"] = translate_to_language
        if encoding:
            params["encoding"] = encoding

        query_string = "&".join([f"{k}={v}" for k, v in params.items()])
        base_url = self._client_wrapper.get_base_url()
        
        ws_base = base_url
        if base_url.startswith("https://"):
            ws_base = base_url.replace("https://", "wss://", 1)
        elif base_url.startswith("http://"):
            ws_base = base_url.replace("http://", "ws://", 1)
        
        full_url = f"{ws_base.rstrip('/')}/transcription/listen?{query_string}"
        headers = self._client_wrapper.get_headers()
        
        return ListenConnection(url=full_url, headers=headers)

class AsyncListenV1Client:
    def __init__(self, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    def connect(
        self,
        *,
        sample_rate: int,
        channels: int,
        encoding: ENCODING_TYPES,
        model: str = "camb",
        language: str = "en-us",
        translate_to_language: typing.Optional[str] = None,
        punctuate: bool = True,
        diarize: bool = False,
        interim_results: bool = True,
    ) -> AsyncListenConnection:
        params = {
            "model": model,
            "language": language,
            "sample_rate": sample_rate,
            "channels": channels,
            "punctuate": str(punctuate).lower(),
            "diarize": str(diarize).lower(),
            "interim_results": str(interim_results).lower(),
        }
        if translate_to_language:
            params["translate_to_language"] = translate_to_language
        if encoding:
            params["encoding"] = encoding

        query_string = "&".join([f"{k}={v}" for k, v in params.items()])
        base_url = self._client_wrapper.get_base_url()
        
        ws_base = base_url
        if base_url.startswith("https://"):
            ws_base = base_url.replace("https://", "wss://", 1)
        elif base_url.startswith("http://"):
            ws_base = base_url.replace("http://", "ws://", 1)
        
        full_url = f"{ws_base.rstrip('/')}/transcription/listen?{query_string}"
        headers = self._client_wrapper.get_headers()
        
        return AsyncListenConnection(url=full_url, headers=headers)
