from __future__ import annotations

import logging
import os
from dataclasses import dataclass
from typing import Any

import numpy as np

from speech_to_speech.pipeline.messages import TTSInput

logger = logging.getLogger(__name__)

_TRUE_VALUES = {"1", "true", "yes", "on"}


@dataclass(slots=True)
class DelayFillerConfig:
    enabled: bool
    threshold_s: float
    short_phrases: list[str]
    full_phrases: list[str]


def _split_env_list(name: str) -> list[str]:
    raw = os.environ.get(name, "").strip()
    return [part.strip() for part in raw.split("|") if part.strip()]


def _env_flag(name: str, *, default: bool) -> bool:
    raw = os.environ.get(name)
    if raw is None:
        return default
    return raw.strip().lower() in _TRUE_VALUES


def load_delay_filler_config() -> DelayFillerConfig:
    short_phrases = _split_env_list("TTS_DELAY_FILLERS_SHORT_ES")
    full_phrases = _split_env_list("TTS_DELAY_FILLERS_FULL_ES")

    # Backward compatibility with the old single-list variable.
    if not short_phrases and not full_phrases:
        full_phrases = _split_env_list("TTS_DELAY_FILLERS_ES")

    enabled = _env_flag("TTS_DELAY_FILLERS_ENABLED", default=bool(short_phrases or full_phrases))
    threshold_ms_raw = os.environ.get("TTS_DELAY_FILLERS_THRESHOLD_MS", "1200").strip() or "1200"
    try:
        threshold_ms = max(0, int(threshold_ms_raw))
    except ValueError:
        logger.warning("Invalid TTS_DELAY_FILLERS_THRESHOLD_MS=%r; using 1200", threshold_ms_raw)
        threshold_ms = 1200
    return DelayFillerConfig(
        enabled=enabled and bool(short_phrases or full_phrases),
        threshold_s=threshold_ms / 1000.0,
        short_phrases=short_phrases,
        full_phrases=full_phrases,
    )


def _chunk_to_bytes(chunk: Any) -> bytes:
    audio = getattr(chunk, "audio", chunk)
    if isinstance(audio, np.ndarray) or hasattr(audio, "tobytes"):
        return audio.tobytes()
    if isinstance(audio, bytes):
        return audio
    raise TypeError(f"Unsupported delay filler audio chunk type: {type(audio)!r}")


def pregenerate_delay_filler_clips(tts_handler: Any, phrases: list[str]) -> list[bytes]:
    clips: list[bytes] = []
    for phrase in phrases:
        try:
            clip = b"".join(
                _chunk_to_bytes(chunk)
                for chunk in tts_handler.process(TTSInput(text=phrase, language_code="es"))
            )
        except Exception:
            logger.exception("Failed to pregenerate TTS delay filler for phrase %r", phrase)
            continue
        if not clip:
            logger.warning("Discarding empty TTS delay filler for phrase %r", phrase)
            continue
        clips.append(clip)
    return clips
