"""Cartesia TTS implementation using their REST API."""

from __future__ import annotations

import io
import logging

import numpy as np
import soundfile as sf

from roohai.base import TTSModel

logger = logging.getLogger(__name__)


class CartesiaTTS(TTSModel):
    META = {
        "display_name": "Cartesia",
        "description": "Cloud-based TTS API with fast, natural-sounding voices. Requires API key.",
        "kind": "cloud",
        "pip_dependencies": ["cartesia"],
        "hf_models": [],
        "estimated_download_mb": 0,
        "config_fields": [
            {
                "name": "api_key",
                "label": "API Key",
                "type": "secret",
                "required": True,
                "env_var": "CARTESIA_API_KEY",
                "placeholder": "sk-xxx",
            },
            {
                "name": "model_id",
                "label": "Model ID",
                "type": "text",
                "required": False,
                "default": "sonic-2",
            },
            {
                "name": "voice_id",
                "label": "Voice ID",
                "type": "text",
                "required": False,
                "default": "a0e99841-438c-4a64-b679-ae501e7d6091",
            },
            {
                "name": "language",
                "label": "Language",
                "type": "text",
                "required": False,
                "default": "en",
            },
            {
                "name": "sample_rate",
                "label": "Sample Rate",
                "type": "text",
                "required": False,
                "default": "24000",
            },
        ],
    }

    def __init__(
        self,
        api_key: str | None = None,
        model_id: str = "sonic-2",
        voice_id: str = "a0e99841-438c-4a64-b679-ae501e7d6091",  # Default English voice
        language: str = "en",
        sample_rate: int = 24000,
        **kwargs,
    ) -> None:
        self.model_id = model_id
        self.voice_id = voice_id
        self.language = language
        self.sample_rate = int(sample_rate)
        self._api_key = api_key
        self._client = None

    def load(self) -> None:
        import os

        from cartesia import Cartesia

        key = self._api_key or os.environ.get("CARTESIA_API_KEY")
        if not key:
            raise RuntimeError(
                "Cartesia API key required. Set CARTESIA_API_KEY env var or pass api_key in config."
            )
        self._client = Cartesia(api_key=key)

    def synthesize(self, text: str) -> tuple[np.ndarray, int]:
        if not self.is_loaded:
            raise RuntimeError("Model not loaded. Call load() first.")

        response = self._client.tts.generate(
            model_id=self.model_id,
            transcript=text,
            voice={"mode": "id", "id": self.voice_id},
            output_format={
                "container": "wav",
                "encoding": "pcm_s16le",
                "sample_rate": self.sample_rate,
            },
            language=self.language,
        )
        output = b"".join(response.iter_bytes())
        data, sr = sf.read(io.BytesIO(output), dtype="float32")
        if data.ndim > 1:
            data = data.mean(axis=1)
        return data, sr

    def unload(self) -> None:
        if self._client is not None:
            if hasattr(self._client, 'close'):
                self._client.close()
            self._client = None

    @property
    def is_loaded(self) -> bool:
        return self._client is not None
