from __future__ import annotations

import os
from pathlib import Path


def load_env_file(path: Path) -> None:
    if not path.exists():
        return
    for raw in path.read_text(encoding="utf-8").splitlines():
        line = raw.strip()
        if not line or line.startswith("#") or "=" not in line:
            continue
        key, value = line.split("=", 1)
        os.environ.setdefault(key.strip(), value.strip().strip('"').strip("'"))


def env_bool(name: str, default: bool = False) -> bool:
    value = os.getenv(name)
    if value is None:
        return default
    return value.strip().lower() in {"1", "true", "yes", "on"}


def env_int(name: str, default: int, minimum: int, maximum: int) -> int:
    try:
        value = int(os.getenv(name, str(default)))
    except ValueError:
        value = default
    return min(maximum, max(minimum, value))


def env_float(name: str, default: float, minimum: float, maximum: float) -> float:
    try:
        value = float(os.getenv(name, str(default)))
    except ValueError:
        value = default
    return min(maximum, max(minimum, value))


def project_root() -> Path:
    return Path(__file__).resolve().parents[2]


def env_path(name: str, default: Path) -> Path:
    value = os.getenv(name, "").strip()
    return Path(value).expanduser().resolve() if value else default.resolve()


def load_runtime_config() -> dict[str, object]:
    root = project_root()
    load_env_file(root / ".env")
    instance = env_path("KIMU_INSTANCE_DIR", root / "instance")
    instance.mkdir(parents=True, exist_ok=True)
    storage = env_path("KIMU_STORAGE_DIR", instance / "files")
    storage.mkdir(parents=True, exist_ok=True)
    return {
        "PROJECT_ROOT": root,
        "INSTANCE_DIR": instance,
        "STORAGE_DIR": storage,
        "DATABASE": instance / "kimu.sqlite3",
        "SECRET_KEY": os.getenv("KIMU_SECRET_KEY", "development-only-change-me"),
        "MASTER_KEY": os.getenv("KIMU_MASTER_KEY", ""),
        "MASTER_KEY_VERSION": env_int("KIMU_MASTER_KEY_VERSION", 1, 1, 9999),
        "TOGETHER_API_KEY": os.getenv("TOGETHER_API_KEY", ""),
        "TOGETHER_BASE_URL": os.getenv("TOGETHER_BASE_URL", "https://api.together.ai/v1").rstrip("/"),
        "K26_MODEL_ID": os.getenv("KIMU_K26_MODEL_ID", "moonshotai/Kimi-K2.6"),
        "K27_MODEL_ID": os.getenv("KIMU_K27_MODEL_ID", "moonshotai/Kimi-K2.7-Code"),
        "K27_CONFIGURED": env_bool("KIMU_K27_CONFIGURED", False),
        "FAKE_PROVIDER": env_bool("KIMU_FAKE_PROVIDER", False),
        "COOKIE_SECURE": env_bool("KIMU_COOKIE_SECURE", False),
        "WORKER_COUNT": env_int("KIMU_WORKERS", 1, 1, 64),
        "SINGLE_WORKER_REQUIRED": True,
        "MAX_MESSAGE_CHARS": env_int("KIMU_MAX_MESSAGE_CHARS", 32000, 1000, 250000),
        "MAX_CONTEXT_MESSAGES": env_int("KIMU_MAX_CONTEXT_MESSAGES", 80, 4, 500),
        "MAX_UPLOAD_BYTES": env_int("KIMU_MAX_UPLOAD_BYTES", 512 * 1024 * 1024, 1024 * 1024, 2 * 1024 * 1024 * 1024),
        "MAX_ATTACHMENTS_PER_MESSAGE": env_int("KIMU_MAX_ATTACHMENTS_PER_MESSAGE", 12, 1, 50),
        "WHISPER_MODEL_ID": os.getenv("KIMU_WHISPER_MODEL_ID", "openai/whisper-large-v3"),
        "SONIC_MODEL_ID": os.getenv("KIMU_SONIC_MODEL_ID", "cartesia/sonic-3"),
        "TOGETHER_STT_WS_URL": os.getenv("KIMU_TOGETHER_STT_WS_URL", "wss://api.together.ai/v1/realtime"),
        "TOGETHER_TTS_WS_URL": os.getenv("KIMU_TOGETHER_TTS_WS_URL", "wss://api.together.ai/v1/audio/speech/websocket"),
        "TTS_SAMPLE_RATE": env_int("KIMU_TTS_SAMPLE_RATE", 24000, 16000, 48000),
        "MAX_AUDIO_FRAME_BYTES": env_int("KIMU_MAX_AUDIO_FRAME_BYTES", 262144, 4096, 2 * 1024 * 1024),
        "TTS_DEFAULT_VOICE": os.getenv("KIMU_TTS_DEFAULT_VOICE", "tara"),
        "TTS_VOICES": [value.strip() for value in os.getenv("KIMU_TTS_VOICES", "tara,sonic-3-default").split(",") if value.strip()],
        "AUDIO_VAD_DEFAULTS": {
            "type": "server_vad",
            "threshold": env_float("KIMU_VAD_THRESHOLD", 0.3, 0.05, 0.95),
            "min_silence_duration_ms": env_int("KIMU_VAD_MIN_SILENCE_MS", 550, 100, 5000),
            "min_speech_duration_ms": env_int("KIMU_VAD_MIN_SPEECH_MS", 200, 50, 5000),
            "max_speech_duration_s": env_int("KIMU_VAD_MAX_SPEECH_S", 45, 2, 300),
            "speech_pad_ms": env_int("KIMU_VAD_SPEECH_PAD_MS", 250, 0, 2000),
        },
    }
