"""Team configuration models."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from evented.configs import EventConfig
from pydantic import ConfigDict, Field, ImportString
from schemez import Schema

from llmling_agent_config.event_handlers import EventHandlerConfig
from llmling_agent_config.forward_targets import ForwardingTarget
from llmling_agent_config.mcp_server import (
    BaseMCPServerConfig,
    MCPServerConfig,
    StdioMCPServerConfig,
)


if TYPE_CHECKING:
    from llmling_agent.common_types import IndividualEventHandler


class NodeConfig(Schema):
    """Configuration for a Node of the messaging system."""

    model_config = ConfigDict(
        frozen=True,
        arbitrary_types_allowed=True,
        json_schema_extra={
            "x-icon": "octicon:workflow-16",
            "x-doc-title": "Node Configuration",
        },
    )

    name: str | None = Field(default=None)
    """Identifier for the node. Set from dict key, not from YAML."""

    config_file_path: str | None = Field(
        default=None,
        examples=["/path/to/config.yml", "configs/agent.yaml"],
        title="Configuration file path",
    )
    """Config file path for resolving relative paths."""

    display_name: str | None = Field(
        default=None,
        examples=["Main Agent", "Web Searcher", "Code Assistant"],
        title="Display name",
    )
    """Human-readable display name for the node."""

    description: str | None = Field(
        default=None,
        examples=["Main conversation agent", "Handles web search requests"],
        title="Node description",
    )
    """Optional description of the agent / team."""

    triggers: list[EventConfig] = Field(
        default_factory=list,
        examples=[
            [
                {
                    "type": "time",
                    "name": "daily_check",
                    "schedule": "0 9 * * *",
                    "prompt": "Daily status update",
                }
            ],
            [
                {
                    "type": "file",
                    "name": "code_watcher",
                    "paths": ["./src"],
                    "extensions": [".py"],
                }
            ],
        ],
        title="Event triggers",
    )
    """Event sources that activate this agent / team"""

    connections: list[ForwardingTarget] = Field(
        default_factory=list,
        examples=[
            [
                {
                    "type": "node",
                    "name": "output_agent",
                    "connection_type": "run",
                    "wait_for_completion": True,
                }
            ],
            [
                {
                    "type": "file",
                    "path": "logs/messages.txt",
                    "template": "{{ message.content }}",
                }
            ],
        ],
        title="Message forwarding targets",
    )
    """Targets to forward results to."""

    mcp_servers: list[str | MCPServerConfig] = Field(
        default_factory=list,
        title="MCP servers",
        examples=[
            ["uvx some-server"],
            [{"type": "streamable-http", "url": "http://mcp.example.com"}],
        ],
    )
    """List of MCP server configurations:
    - str entries are converted to StdioMCPServerConfig
    - MCPServerConfig for full server configuration
    """
    # Any should be InputProvider, but this leads to circular import
    input_provider: ImportString[Any] | None = Field(
        default=None,
        title="Input provider",
    )
    """Provider for human-input-handling."""

    event_handlers: list[EventHandlerConfig] = Field(
        default_factory=list,
        title="Event handlers",
        examples=[
            [{"type": "builtin", "handler": "simple"}],
        ],
    )
    """Event handlers for processing agent stream events.

    Supports:
    - builtin: Simple/detailed console output
    - tts: Text-to-speech synthesis
    - callback: Custom handler via import path
    """

    def get_event_handlers(self) -> list[IndividualEventHandler]:
        """Get resolved event handlers from configuration.

        Returns:
            List of event handler callables.
        """
        from llmling_agent_config.event_handlers import resolve_handler_configs

        return resolve_handler_configs(self.event_handlers)

    def get_mcp_servers(self) -> list[MCPServerConfig]:
        """Get processed MCP server configurations.

        Converts string entries to StdioMCPServerConfigs by splitting
        into command and arguments.

        Returns:
            List of MCPServerConfig instances

        Raises:
            ValueError: If string entry is empty
        """
        configs: list[MCPServerConfig] = []

        for server in self.mcp_servers:
            match server:
                case str():
                    parts = server.split()
                    if not parts:
                        msg = "Empty MCP server command"
                        raise ValueError(msg)

                    configs.append(StdioMCPServerConfig(command=parts[0], args=parts[1:]))
                case BaseMCPServerConfig():
                    configs.append(server)

        return configs
