import base64

import httpx

from spaik_sdk.audio.options import TTSOptions

GOOGLE_GENERATIVE_ENDPOINT = "https://generativelanguage.googleapis.com/v1beta/models"


async def synthesize(
    text: str,
    model: str,
    api_key: str,
    options: TTSOptions,
    endpoint: str | None = None,
    headers: dict[str, str] | None = None,
) -> bytes:
    """
    Synthesize speech using Google's Gemini TTS API.

    Args:
        text: The text to convert to speech
        model: The model to use (e.g., "gemini-2.5-flash-tts", "gemini-2.5-pro-tts")
        api_key: Google API key
        options: TTS options
        endpoint: Optional custom endpoint
        headers: Optional additional headers

    Returns:
        Audio bytes (WAV format from Gemini)
    """
    base_url = endpoint or GOOGLE_GENERATIVE_ENDPOINT
    url = f"{base_url}/{model}:generateContent?key={api_key}"

    request_headers = {
        "Content-Type": "application/json",
    }
    if headers:
        request_headers.update(headers)

    # Build the speech config
    speech_config: dict = {
        "voiceConfig": {
            "prebuiltVoiceConfig": {
                "voiceName": options.voice,
            }
        }
    }

    generation_config: dict = {
        "responseModalities": ["AUDIO"],
        "speechConfig": speech_config,
    }
    generation_config.update(options.vendor)

    payload = {
        "contents": [{"parts": [{"text": text}]}],
        "generationConfig": generation_config,
    }

    async with httpx.AsyncClient(timeout=120.0) as client:
        response = await client.post(url, headers=request_headers, json=payload)
        if response.status_code != 200:
            raise ValueError(f"Google TTS API error {response.status_code}: {response.text}")
        data = response.json()

    candidates = data.get("candidates", [])
    if not candidates:
        raise ValueError("No audio generated by Gemini TTS API")

    parts = candidates[0].get("content", {}).get("parts", [])
    for part in parts:
        if "inlineData" in part:
            audio_b64 = part["inlineData"]["data"]
            return base64.b64decode(audio_b64)

    raise ValueError("No audio data found in Gemini TTS API response")
