"""Configuration. Each field names a backend; the factory maps names -> classes.

Defaults are all "mock" so the skeleton runs out of the box. Flip individual
fields (via env or code) as real backends land.

Env overrides (optional):
    WSAI_SOURCE, WSAI_VISION, WSAI_STT, WSAI_TTS, WSAI_BRAIN, WSAI_TEXT
    WSAI_CAPTURE_INTERVAL
"""

from __future__ import annotations

import os
from dataclasses import dataclass


@dataclass
class Settings:
    source: str | None = "mock"  # mock | mss | None (eyes-free)
    vision: str | None = "mock"  # mock | claude | None (eyes-free)
    stt: str | None = "mock"     # mock | whisper   | None
    tts: str | None = "mock"     # mock | melo      | None
    brain: str = "mock"          # mock | claude
    text: str | None = None      # None | (discord)

    capture_interval: float = 1.5
    anthropic_model: str = "claude-sonnet-4-5"

    @classmethod
    def from_env(cls) -> "Settings":
        def opt(name: str, default):
            v = os.environ.get(name)
            return default if v is None else (None if v.lower() == "none" else v)

        return cls(
            source=opt("WSAI_SOURCE", "mock"),
            vision=opt("WSAI_VISION", "mock"),
            stt=opt("WSAI_STT", "mock"),
            tts=opt("WSAI_TTS", "mock"),
            brain=opt("WSAI_BRAIN", "mock"),
            text=opt("WSAI_TEXT", None),
            capture_interval=float(os.environ.get("WSAI_CAPTURE_INTERVAL", "1.5")),
        )

    @classmethod
    def mock(cls) -> "Settings":
        return cls()

    @classmethod
    def live(cls) -> "Settings":
        """A realistic local config: capture this screen, Claude eyes+brain,
        mock voice (until STT/TTS backends are wired)."""
        return cls(source="mss", vision="claude", brain="claude", stt="mock", tts="mock")

    @classmethod
    def voice(cls) -> "Settings":
        """Eyes-free voice loop: no screen share, just STT -> Brain -> TTS.

        Screen capture is deferred, so source/vision are off. Backends default
        to mock so it runs out of the box; flip stt/tts/brain to real ones as
        they land."""
        return cls(source=None, vision=None, stt="mock", tts="mock", brain="mock")
