"""Configuration for the voice control node."""

from __future__ import annotations

import os
from dataclasses import dataclass
from typing import Dict, Optional, Tuple

# Image encoding constants
JPEG_QUALITY = 80


@dataclass
class VoiceConfig:
    """Configuration for voice control."""

    host: str
    port: int
    tcp_offset_mm: float
    approach_offset_mm: float
    step_mm: float
    default_roll: float
    default_pitch: float
    default_yaw: float
    dry_run: bool
    workspace_min: Tuple[Optional[float], Optional[float], Optional[float]]
    workspace_max: Tuple[Optional[float], Optional[float], Optional[float]]
    class_map: Dict[str, str]


@dataclass
class ApiConfig:
    """Configuration for the web API server."""

    host: str
    port: int
    enabled: bool


@dataclass
class LLMConfig:
    """Configuration for LLM provider."""

    provider: str  # "rules", "gemini", "ollama", "openai"
    model: str  # Model name/path
    api_base: Optional[str] = None  # For Ollama
    temperature: float = 0.3


def _parse_float_env(name: str) -> Optional[float]:
    """Parse an optional float from environment variable."""
    raw = os.getenv(name)
    if raw is None or raw == "":
        return None
    try:
        return float(raw)
    except ValueError:
        return None


def _parse_class_map(raw: str) -> Dict[str, str]:
    """Parse JSON class mapping from string."""
    import json
    import time

    if not raw:
        return {}
    try:
        data = json.loads(raw)
        if isinstance(data, dict):
            return {str(k): str(v) for k, v in data.items()}
    except Exception as e:
        timestamp = time.strftime("%H:%M:%S")
        print(f"[voice_control {timestamp}] Warning: failed to parse CLASS_MAP: {e}", flush=True)
    return {}


def load_voice_config() -> VoiceConfig:
    """Load voice configuration from environment variables."""
    return VoiceConfig(
        host="",
        port=0,
        tcp_offset_mm=float(os.getenv("TCP_OFFSET_MM", "63.0")),
        approach_offset_mm=float(os.getenv("APPROACH_OFFSET_MM", "50.0")),
        step_mm=float(os.getenv("STEP_MM", "20.0")),
        default_roll=float(os.getenv("DEFAULT_ROLL", "180.0")),
        default_pitch=float(os.getenv("DEFAULT_PITCH", "0.0")),
        default_yaw=float(os.getenv("DEFAULT_YAW", "0.0")),
        dry_run=os.getenv("DRY_RUN", "false").lower() in ("true", "1", "yes"),
        workspace_min=(
            _parse_float_env("WORKSPACE_MIN_X"),
            _parse_float_env("WORKSPACE_MIN_Y"),
            _parse_float_env("WORKSPACE_MIN_Z"),
        ),
        workspace_max=(
            _parse_float_env("WORKSPACE_MAX_X"),
            _parse_float_env("WORKSPACE_MAX_Y"),
            _parse_float_env("WORKSPACE_MAX_Z"),
        ),
        class_map=_parse_class_map(os.getenv("CLASS_MAP", "")),
    )


def load_api_config() -> ApiConfig:
    """Load API server configuration from environment variables."""
    return ApiConfig(
        host=os.getenv("API_HOST", "0.0.0.0"),
        port=int(os.getenv("API_PORT", "9001")),
        enabled=os.getenv("API_ENABLED", "true").lower() in ("true", "1", "yes"),
    )


def load_llm_config() -> LLMConfig:
    """Load LLM configuration from environment variables."""
    return LLMConfig(
        provider=os.getenv("LLM_PROVIDER", "rules").lower(),
        model=os.getenv("LLM_MODEL", "gemma2"),
        api_base=os.getenv("OLLAMA_API_BASE", "http://localhost:11434"),
        temperature=float(os.getenv("LLM_TEMPERATURE", "0.3")),
    )
