"""
RingAI Configuration Module

Centralized configuration loading and constants for all RingAI components.
"""

import os
import logging
from pathlib import Path
from dataclasses import dataclass, field
from typing import Optional

# =========================
# Environment Loading
# =========================

def load_env_file(env_path: Optional[Path] = None):
    """Load environment variables from .env file if it exists"""
    if env_path is None:
        env_path = Path(__file__).parent.parent / ".env"

    if env_path.exists():
        with open(env_path) as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith("#"):
                    key, _, value = line.partition("=")
                    key = key.strip()
                    value = value.strip().strip('"').strip("'")
                    if key and value:
                        os.environ.setdefault(key, value)

# Load .env on import
load_env_file()


# =========================
# Audio Constants
# =========================

SAMPLE_RATE_IN = 8000       # Twilio input (µ-law)
SAMPLE_RATE_OUT = 16000     # Whisper output
BYTES_PER_SAMPLE = 2        # 16-bit PCM

BUFFER_DURATION_SEC = 1
BUFFER_SIZE = SAMPLE_RATE_IN * BYTES_PER_SAMPLE * BUFFER_DURATION_SEC


# =========================
# VAD Settings
# =========================

VAD_FRAME_MS = int(os.getenv("VAD_FRAME_MS", "20"))
END_SILENCE_MS = int(os.getenv("END_SILENCE_MS", "900"))
MIN_UTTERANCE_MS = int(os.getenv("MIN_UTTERANCE_MS", "300"))

MIN_RMS_THRESHOLD = int(os.getenv("MIN_RMS_THRESHOLD", "400"))
NOISE_MULTIPLIER = float(os.getenv("NOISE_MULTIPLIER", "4.0"))
NOISE_EMA_ALPHA = float(os.getenv("NOISE_EMA_ALPHA", "0.05"))

FRAME_BYTES_8K = int(SAMPLE_RATE_IN * (VAD_FRAME_MS / 1000.0) * BYTES_PER_SAMPLE)
MIN_PCM_BYTES_8K = int(0.4 * SAMPLE_RATE_IN * BYTES_PER_SAMPLE)  # ~400ms


# =========================
# Dataset Paths
# =========================

DATASET_ROOT = os.getenv("DATASET_ROOT", "dataset")
CALLS_ROOT = os.path.join(DATASET_ROOT, "calls")


# =========================
# Whisper Settings
# =========================

WHISPER_MODEL_NAME = os.getenv("WHISPER_MODEL_NAME", "small")
WHISPER_LANGUAGE = os.getenv("WHISPER_LANGUAGE", "en")
WHISPER_FP16 = os.getenv("WHISPER_FP16", "false").lower() in ("1", "true", "yes", "on")

WHISPER_INITIAL_PROMPT = os.getenv(
    "WHISPER_INITIAL_PROMPT",
    "This is a customer support phone call. "
    "The caller is reporting a technical or service-related issue. "
    "Common topics include internet speed, Wi-Fi, software systems, "
    "customer portals, servers, connectivity problems, account issues, "
    "and service complaints. Use clear professional English."
)


# =========================
# LLM Settings
# =========================

LLM_ENABLED = os.getenv("LLM_ENABLED", "1").lower() in ("1", "true", "yes", "on")
LLM_MODE = os.getenv("LLM_MODE", "mock").lower()  # mock | http
LLM_HTTP_URL = os.getenv("LLM_HTTP_URL", "http://127.0.0.1:9000/v1/chat/completions")
LLM_TIMEOUT_SEC = float(os.getenv("LLM_TIMEOUT_SEC", "10"))
LLM_HISTORY_MAX = int(os.getenv("LLM_HISTORY_MAX", "10"))
LLM_FALLBACK_TO_MOCK = os.getenv("LLM_FALLBACK_TO_MOCK", "1").lower() in ("1", "true", "yes", "on")
LLM_MAX_TOKENS = int(os.getenv("LLM_MAX_TOKENS", "150"))


# =========================
# Twilio Settings
# =========================

TWILIO_ACCOUNT_SID = os.getenv("TWILIO_ACCOUNT_SID")
TWILIO_AUTH_TOKEN = os.getenv("TWILIO_AUTH_TOKEN")
TWILIO_PHONE_NUMBER = os.getenv("TWILIO_PHONE_NUMBER")

WEBSOCKET_URL = os.getenv("WEBSOCKET_URL", "wss://ringai.southernaccountancy.com/media-stream")
STREAM_REDIRECT_URL = os.getenv("STREAM_REDIRECT_URL", "https://ringai.southernaccountancy.com/stream")


# =========================
# Conversation Settings
# =========================

AI_SPEAK_COOLDOWN_SEC = float(os.getenv("AI_SPEAK_COOLDOWN_SEC", "1"))
MAX_CLARIFICATION_COUNT = int(os.getenv("MAX_CLARIFICATION_COUNT", "4"))
STALE_CALL_TIMEOUT_SEC = int(os.getenv("STALE_CALL_TIMEOUT_SEC", "30"))


# =========================
# Logging Configuration
# =========================

LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()


def setup_logging():
    """Configure logging for all RingAI modules"""
    logging.basicConfig(
        level=LOG_LEVEL,
        format="[%(levelname)s] %(name)s | %(message)s",
    )

    # Suppress noisy loggers
    logging.getLogger("whisper").setLevel(logging.ERROR)

    return {
        "call": logging.getLogger("ivr.call"),
        "audio": logging.getLogger("ivr.audio"),
        "stt": logging.getLogger("ivr.stt"),
        "llm": logging.getLogger("ivr.llm"),
        "ws": logging.getLogger("ivr.ws"),
    }


# Pre-configured loggers (available after setup_logging() is called)
loggers = setup_logging()

log_call = loggers["call"]
log_audio = loggers["audio"]
log_stt = loggers["stt"]
log_llm = loggers["llm"]
log_ws = loggers["ws"]


# =========================
# Validation
# =========================

def validate_twilio_credentials():
    """Validate that Twilio credentials are set"""
    if not TWILIO_ACCOUNT_SID or not TWILIO_AUTH_TOKEN:
        raise RuntimeError(
            "Twilio credentials not set. Please set TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN "
            "environment variables or create a .env file with these credentials."
        )


def ensure_directories():
    """Create required directories"""
    os.makedirs(CALLS_ROOT, exist_ok=True)
