"""Configuration loaded from environment / .env file."""

from pathlib import Path

from pydantic_settings import BaseSettings


class Settings(BaseSettings):
    model_config = {"env_prefix": "TTS_", "env_file": ".env", "extra": "ignore"}

    # Server
    host: str = "0.0.0.0"
    port: int = 8371

    # Piper (Wyoming protocol)
    piper_host: str = "172.26.0.3"
    piper_port: int = 10200

    # Kokoro (ONNX)
    kokoro_model: Path = Path("models/kokoro/kokoro-v1.0.onnx")
    kokoro_voices: Path = Path("models/kokoro/voices-v1.0.bin")

    # Orpheus (llama-server + SNAC)
    orpheus_url: str = "http://127.0.0.1:8081"

    # Voice filtering
    voice_blacklist: str = "am_adam,af_jessica"

    # Audio output (empty = system temp dir)
    audio_dir: str = ""

    # Voice identity (project-aware voice assignment)
    voice_identity: bool = True
    announce_project: bool = False
    # Comma-separated prefixes for auto-assignment pool (English voices)
    voice_identity_prefixes: str = "af_,am_,bf_,bm_,ef_,em_"
    # Voices available explicitly but excluded from auto-assignment (e.g. whispery)
    voice_identity_exclude: str = "af_nicole"
    # JSON file to persist project->voice assignments across restarts
    voice_identity_file: str = ""

    # Entry tone before speech: "chirp", "apollo", "none", or path to custom WAV
    entry_tone: str = "chirp"

    # Exit tone after speech: "roger", "quindar-out", "none", or path to custom WAV
    # When more items are queued, plays "standby" (ascending blip) instead
    exit_tone: str = "roger"

    # Cancel tone: "scratch", "reverse-roger", "none", or path to custom WAV
    cancel_tone: str = "scratch"

    # Media ducking
    duck_media: bool = True
    duck_fade_out_ms: int = 500
    duck_fade_in_ms: int = 1000

    # Graceful shutdown: max seconds to wait for current speech to finish
    shutdown_timeout: float = 30.0

    @property
    def blacklisted_voices(self) -> set[str]:
        return {v.strip().lower() for v in self.voice_blacklist.split(",") if v.strip()}

    @property
    def output_dir(self) -> Path:
        if self.audio_dir:
            p = Path(self.audio_dir)
            p.mkdir(parents=True, exist_ok=True)
            return p
        return Path("/tmp/mcspeak")


settings = Settings()
