"""ElevenLabs Text-to-Speech (TTS) provider adapter.

This module integrates the official ElevenLabs Python SDK into api_sdk's
bytes-oriented TTS interface.

Environment variables (or pass explicitly):
- ELEVENLABS_API_KEY
- ELEVENLABS_VOICE_ID (required unless passed via `voice_id`)
- ELEVENLABS_MODEL_ID (default: eleven_multilingual_v2)
- ELEVENLABS_OUTPUT_FORMAT (default: mp3_44100_128)
"""

from __future__ import annotations

import logging
import os
from typing import Iterable, Optional, Union

from ._env import load_env_once


logger = logging.getLogger(__name__)


DEFAULT_ELEVENLABS_TTS_MODEL = "eleven_multilingual_v2"
DEFAULT_ELEVENLABS_OUTPUT_FORMAT = "mp3_44100_128"
DEFAULT_ELEVENLABS_VOICE_ID = "DowyQ68vDpgFYdWVGjc3"


def _to_bytes(audio: Union[bytes, bytearray, Iterable[bytes]]) -> bytes:
    if isinstance(audio, (bytes, bytearray)):
        return bytes(audio)
    return b"".join(bytes(chunk) for chunk in audio)


def synthesize_speech_elevenlabs_bytes(
    *,
    text: str,
    voice_id: Optional[str] = None,
    model_id: Optional[str] = None,
    output_format: Optional[str] = None,
    api_key: Optional[str] = None,
) -> bytes:
    """Synthesize speech with ElevenLabs and return raw audio bytes."""
    if not text or not isinstance(text, str):
        raise ValueError("text must be a non-empty string")

    load_env_once()
    api_key = api_key or os.environ.get("ELEVENLABS_API_KEY")
    if not api_key:
        raise ValueError("Missing ElevenLabs API key: set ELEVENLABS_API_KEY (or pass api_key).")

    voice_id = voice_id or os.environ.get("ELEVENLABS_VOICE_ID") or DEFAULT_ELEVENLABS_VOICE_ID

    model_id = model_id or os.environ.get("ELEVENLABS_MODEL_ID") or DEFAULT_ELEVENLABS_TTS_MODEL
    output_format = output_format or os.environ.get("ELEVENLABS_OUTPUT_FORMAT") or DEFAULT_ELEVENLABS_OUTPUT_FORMAT

    # Lazy import to keep ElevenLabs optional unless this provider is used.
    from elevenlabs.client import ElevenLabs

    client = ElevenLabs(api_key=api_key)
    audio = client.text_to_speech.convert(
        text=text,
        voice_id=voice_id,
        model_id=model_id,
        output_format=output_format,
    )
    return _to_bytes(audio)


__all__ = [
    "synthesize_speech_elevenlabs_bytes",
    "DEFAULT_ELEVENLABS_TTS_MODEL",
    "DEFAULT_ELEVENLABS_OUTPUT_FORMAT",
    "DEFAULT_ELEVENLABS_VOICE_ID",
]
