import base64

import httpx

from app.providers.stt.base import STTProvider


class OpenRouterSTTProvider(STTProvider):
    def __init__(self, api_key: str, model: str):
        self.api_key = (api_key or "").strip()
        self.model = (model or "").strip()

    async def transcribe(self, audio_bytes: bytes, fmt: str, language: str | None = None) -> str:
        if not self.api_key:
            raise ValueError("OPENROUTER_API_KEY is empty")
        if not self.model:
            raise ValueError("OPENROUTER_STT_MODEL is empty")
        if not audio_bytes:
            raise ValueError("STT input audio is empty")

        # OpenRouter /audio/transcriptions erwartet JSON mit base64-Audio
        # (NICHT multipart/form-data). Quelle: OpenRouter-Doku (STT).
        payload = {
            "model": self.model,
            "input_audio": {
                "data": base64.b64encode(audio_bytes).decode("utf-8"),
                "format": fmt,
            },
        }
        if language:
            payload["language"] = language

        timeout = httpx.Timeout(connect=10.0, read=120.0, write=30.0, pool=10.0)

        async with httpx.AsyncClient(timeout=timeout) as client:
            try:
                response = await client.post(
                    "https://openrouter.ai/api/v1/audio/transcriptions",
                    headers={
                        "Authorization": f"Bearer {self.api_key}",
                        "Content-Type": "application/json",
                    },
                    json=payload,
                )
                response.raise_for_status()
            except httpx.HTTPStatusError as exc:
                raise RuntimeError(
                    f"OpenRouter STT error {exc.response.status_code}: {exc.response.text}"
                ) from exc
            except httpx.TimeoutException as exc:
                raise RuntimeError("OpenRouter STT timeout") from exc
            except httpx.HTTPError as exc:
                raise RuntimeError(f"OpenRouter STT transport error: {exc}") from exc

        data = response.json()
        return data.get("text", "")

    async def transcribe_detect(
        self, audio_bytes: bytes, fmt: str, language: str | None = None
    ) -> tuple[str, str | None]:
        if not self.api_key:
            raise ValueError("OPENROUTER_API_KEY is empty")
        if not self.model:
            raise ValueError("OPENROUTER_STT_MODEL is empty")
        if not audio_bytes:
            raise ValueError("STT input audio is empty")

        payload = {
            "model": self.model,
            "input_audio": {
                "data": base64.b64encode(audio_bytes).decode("utf-8"),
                "format": fmt,
            },
        }
        if language:
            payload["language"] = language

        timeout = httpx.Timeout(connect=10.0, read=120.0, write=30.0, pool=10.0)
        async with httpx.AsyncClient(timeout=timeout) as client:
            try:
                response = await client.post(
                    "https://openrouter.ai/api/v1/audio/transcriptions",
                    headers={
                        "Authorization": f"Bearer {self.api_key}",
                        "Content-Type": "application/json",
                    },
                    json=payload,
                )
                response.raise_for_status()
            except httpx.HTTPStatusError as exc:
                raise RuntimeError(
                    f"OpenRouter STT error {exc.response.status_code}: {exc.response.text}"
                ) from exc
            except httpx.TimeoutException as exc:
                raise RuntimeError("OpenRouter STT timeout") from exc
            except httpx.HTTPError as exc:
                raise RuntimeError(f"OpenRouter STT transport error: {exc}") from exc
        data = response.json()
        return data.get("text", ""), data.get("language")
