import os
from typing import Any, MutableMapping


def _env_str(key: str, default: str) -> str:
    """
    Read optional string from env.

    - Variable **unset** → return `default` (often \"\" to defer bot AI to DB/Redis).
    - Variable set to **blank** → return \"\" (explicit defer; never substitute `default`).
    """
    v = os.getenv(key)
    if v is None:
        return default
    s = str(v).strip()
    if s == "":
        return ""
    return s


def get_default_system_prompt() -> str:
    # Empty/unset → defer to `{bid}_bots.prompt` / business_id_bots via cluster API + Redis.
    return _env_str("MCUBE_SYSTEM_PROMPT", "").replace("\\n", "\n")


def get_default_mcube_call_config() -> dict[str, str]:
    """
    Base MCube call config from env. Bot-facing AI fields default to empty so outbound
    (`cluster_bot_cfg` from Django) and Redis `mcube_call_config:*` supply values from
    `livekitvoicebot_cluster`.`{business_id}_bots` / `business_id_bots`.

    Only set MCUBE_* in .env for local smoke tests or when not using business_id+bot_id.
    Technical tuning (chunk ms, gain, …): `tts_gain` scales PCM before μ-law for MCube/PSTN
    (1.0 ≈ unity; values below ~0.8 often sound too quiet on phone lines).
    """
    return {
        "system_prompt": get_default_system_prompt(),
        "first_message": _env_str("MCUBE_FIRST_MESSAGE", "").strip(),
        "llm_model": _env_str("MCUBE_LLM_MODEL", ""),
        "llm_provider": _env_str("MCUBE_LLM_PROVIDER", ""),
        "stt_provider": _env_str("MCUBE_STT_PROVIDER", ""),
        "stt_language_code": _env_str("MCUBE_STT_LANGUAGE_CODE", ""),
        "stt_model_id": _env_str("MCUBE_STT_MODEL_ID", ""),
        "tts_provider": _env_str("MCUBE_TTS_PROVIDER", ""),
        "tts_model": _env_str("MCUBE_TTS_MODEL", ""),
        "tts_voice_id": _env_str("MCUBE_TTS_VOICE_ID", ""),
        "tts_encoding": _env_str("MCUBE_TTS_ENCODING", "pcm_16000"),
        "tts_chunk_ms": _env_str("MCUBE_TTS_CHUNK_MS", "200"),
        "tts_gain": _env_str("MCUBE_TTS_GAIN", "1.05"),
        "playback_pace_factor": _env_str("MCUBE_PLAYBACK_PACE_FACTOR", "1.0"),
        "checkpoint_every": _env_str("MCUBE_CHECKPOINT_EVERY", "10"),
    }


def apply_voice_defaults_to_dict(cfg: MutableMapping[str, Any]) -> None:
    """
    When ``MCUBE_VOICE_SETTINGS_FROM_ENV`` is truthy, overwrite STT/TTS tuning keys in ``cfg``
    with values from ``get_default_mcube_call_config()`` so Redis / cluster bot cannot override
    the voice stack for this process.
    """
    if os.getenv("MCUBE_VOICE_SETTINGS_FROM_ENV", "").strip().lower() not in ("1", "true", "yes"):
        return
    d = get_default_mcube_call_config()
    for k in (
        "stt_provider",
        "stt_language_code",
        "stt_model_id",
        "tts_provider",
        "tts_model",
        "tts_voice_id",
        "tts_encoding",
        "tts_chunk_ms",
        "tts_gain",
    ):
        v = d.get(k)
        if v is None:
            continue
        s = str(v).strip()
        if s:
            cfg[k] = v
