"""Configuration schema using Pydantic."""

from pathlib import Path

from pydantic import BaseModel, Field
from pydantic_settings import BaseSettings


class TelegramConfig(BaseModel):
    """Telegram channel configuration."""
    enabled: bool = Field(
        default=False,
        json_schema_extra={"reload": "warm", "label": "Enable Telegram channel"},
    )
    allow_from: list[str] = Field(
        default_factory=list,
        json_schema_extra={"reload": "warm", "label": "Allowed Telegram user IDs or usernames"},
    )
    proxy: str | None = Field(
        default=None,
        json_schema_extra={"reload": "warm", "label": "HTTP/SOCKS5 proxy URL for Telegram"},
    )


class ChannelsConfig(BaseModel):
    """Configuration for chat channels."""
    telegram: TelegramConfig = Field(default_factory=TelegramConfig)


OAUTH_SUPPORTED_PROVIDERS = {"anthropic", "gemini", "openai"}


class AgentDefaults(BaseModel):
    """Default agent configuration."""
    workspace: str = Field(
        default="~/.ragnarbot/workspace",
        json_schema_extra={"reload": "cold", "label": "Workspace directory path"},
    )
    model: str = Field(
        default="anthropic/claude-opus-4-6",
        json_schema_extra={"reload": "warm", "label": "LLM model identifier (provider/model)"},
    )
    max_context_tokens: int = Field(
        default=200_000,
        json_schema_extra={"reload": "hot", "label": "Maximum context window tokens"},
    )
    auth_method: str = Field(
        default="api_key",
        pattern="^(api_key|oauth)$",
        json_schema_extra={"reload": "warm", "label": "Authentication method (api_key or oauth)"},
    )
    stream_steps: bool = Field(
        default=True,
        json_schema_extra={"reload": "hot", "label": "Send intermediate messages during tool loops"},
    )
    debounce_seconds: float = Field(
        default=0.5,
        json_schema_extra={"reload": "hot", "label": "Batch rapid-fire messages delay (seconds)"},
    )
    context_mode: str = Field(
        default="normal",
        pattern="^(eco|normal|full)$",
        json_schema_extra={"reload": "hot", "label": "Context management mode"},
    )
    trace_mode: bool = Field(
        default=False,
        json_schema_extra={"reload": "hot", "label": "Show tool calls in chat during execution"},
    )
    steering_enabled: bool = Field(
        default=True,
        json_schema_extra={"reload": "hot", "label": "Inject same-session messages into active runs"},
    )


class FallbackConfig(BaseModel):
    """Fallback model configuration."""
    model: str | None = Field(
        default=None,
        json_schema_extra={"reload": "warm", "label": "Fallback model identifier"},
    )
    auth_method: str = Field(
        default="api_key",
        pattern="^(api_key|oauth)$",
        json_schema_extra={"reload": "warm", "label": "Fallback auth method"},
    )
    consecutive_failures_threshold: int = Field(
        default=3,
        json_schema_extra={"reload": "hot", "label": "Failures before fallback mode"},
    )
    recovery_probe_interval: int = Field(
        default=60,
        json_schema_extra={"reload": "hot", "label": "Seconds between primary recovery probes"},
    )


class AgentsConfig(BaseModel):
    """Agent configuration."""
    defaults: AgentDefaults = Field(default_factory=AgentDefaults)
    fallback: FallbackConfig = Field(default_factory=FallbackConfig)


class DaemonConfig(BaseModel):
    """Daemon auto-start configuration."""
    enabled: bool = Field(
        default=False,
        json_schema_extra={"reload": "warm", "label": "Enable daemon auto-start"},
    )


class GatewayConfig(BaseModel):
    """Gateway/server configuration."""
    host: str = Field(
        default="0.0.0.0",
        json_schema_extra={"reload": "warm", "label": "Gateway bind address"},
    )
    port: int = Field(
        default=18790,
        json_schema_extra={"reload": "warm", "label": "Gateway port number"},
    )


class WebSearchConfig(BaseModel):
    """Web search tool configuration."""
    engine: str = Field(
        default="brave",
        pattern="^(brave|duckduckgo)$",
        json_schema_extra={"reload": "hot", "label": "Search engine backend"},
    )
    max_results: int = Field(
        default=10,
        json_schema_extra={"reload": "hot", "label": "Default number of search results"},
    )


class WebToolsConfig(BaseModel):
    """Web tools configuration."""
    search: WebSearchConfig = Field(default_factory=WebSearchConfig)


class ExecToolConfig(BaseModel):
    """Shell exec tool configuration."""
    timeout: int = Field(
        default=60,
        json_schema_extra={"reload": "hot", "label": "Shell command timeout (seconds)"},
    )
    restrict_to_workspace: bool = Field(
        default=False,
        json_schema_extra={"reload": "hot", "label": "Block commands outside workspace"},
    )
    safety_guard: bool = Field(
        default=True,
        json_schema_extra={"reload": "hot", "label": "Enable shell command safety guard"},
    )


class BrowserConfig(BaseModel):
    """Browser automation tool configuration."""
    idle_timeout: int = Field(
        default=600,
        json_schema_extra={"reload": "hot", "label": "Auto-close idle sessions (seconds)"},
    )
    headless: bool = Field(
        default=True,
        json_schema_extra={"reload": "hot", "label": "Run browser in headless mode"},
    )
    viewport_width: int = Field(
        default=1920,
        json_schema_extra={"reload": "hot", "label": "Browser viewport width (pixels)"},
    )
    viewport_height: int = Field(
        default=1080,
        json_schema_extra={"reload": "hot", "label": "Browser viewport height (pixels)"},
    )


class ToolsConfig(BaseModel):
    """Tools configuration."""
    web: WebToolsConfig = Field(default_factory=WebToolsConfig)
    exec: ExecToolConfig = Field(default_factory=ExecToolConfig)
    browser: BrowserConfig = Field(default_factory=BrowserConfig)


class TranscriptionConfig(BaseModel):
    """Voice transcription configuration."""
    provider: str = Field(
        default="none",
        pattern="^(groq|elevenlabs|none)$",
        json_schema_extra={"reload": "warm", "label": "Voice transcription provider"},
    )


class HeartbeatConfig(BaseModel):
    """Heartbeat periodic task configuration."""
    enabled: bool = Field(
        default=True,
        json_schema_extra={"reload": "warm", "label": "Enable periodic heartbeat checks"},
    )
    interval_m: int = Field(
        default=30,
        ge=1,
        json_schema_extra={"reload": "warm", "label": "Heartbeat check interval (minutes)"},
    )


class Config(BaseSettings):
    """Root configuration for ragnarbot."""
    agents: AgentsConfig = Field(default_factory=AgentsConfig)
    channels: ChannelsConfig = Field(default_factory=ChannelsConfig)
    daemon: DaemonConfig = Field(default_factory=DaemonConfig)
    gateway: GatewayConfig = Field(default_factory=GatewayConfig)
    heartbeat: HeartbeatConfig = Field(default_factory=HeartbeatConfig)
    tools: ToolsConfig = Field(default_factory=ToolsConfig)
    transcription: TranscriptionConfig = Field(default_factory=TranscriptionConfig)

    @property
    def workspace_path(self) -> Path:
        """Get expanded workspace path."""
        return Path(self.agents.defaults.workspace).expanduser()

    class Config:
        env_prefix = "RAGNARBOT_"
        env_nested_delimiter = "__"
