"""Router orchestration pattern (classification-based routing to specialists)."""

from __future__ import annotations

import logging
from dataclasses import dataclass
from typing import Any

from cyberbrain26.orchestration.subagent.interface import BaseSubagent
from cyberbrain26.orchestration.subagent.types import SubagentOutput

logger = logging.getLogger(__name__)


@dataclass
class RouterClassification:
    """Classification result from router."""

    agent_type: str  # Type of agent (coder, researcher, evaluator)
    specialty: str  # Specific domain (web, code, analysis)
    confidence: float  # Confidence in classification
    reason: str  # Explanation for routing decision


class RouterPattern(BaseSubagent):
    """Router pattern: classification-based routing to specialized agents.

    Implements the "router" pattern where a cheap classification step determines
    which specialist agent should handle the task. Used when:
    - The appropriate agent isn't known upfront
    - Task requirements become clear only during processing
    - Multiple-domain problems requiring different specialists
    - Dynamic task routing based on content analysis

    Per LangChain: Router is typically a single classification step that dispatches
    to agents without maintaining ongoing conversation state.
    """

    def __init__(self, spec: Any) -> None:
        super().__init__(spec)
        self._router_model: Any = None  # Classifier model (e.g., GPT-4o-mini)
        self._specialist_agents: dict[str, Any] = {}  # agent_type -> agent instance

    def set_router_model(self, model: Any) -> None:
        """Set the router model (typically a cheap classifier)."""
        self._router_model = model
        logger.info("Router pattern set with classifier model")

    def register_specialist(self, agent_type: str, agent: Any) -> None:
        """Register a specialist agent for a given type."""
        self._specialist_agents[agent_type] = agent

    async def invoke(self, input_data: dict[str, Any]) -> SubagentOutput:
        """Execute router pattern: classify and dispatch to specialist.

        Args:
            input_data: Input to classify

        Returns:
            Result from the dispatched specialist agent
        """
        if self._router_model is None:
            return SubagentOutput(
                summary="Router model not configured",
                confidence=0.0,
                requires_human_review=True,
                obstacles=["Router model missing; cannot dispatch"],
            )

        try:
            classification = self._classify_input(input_data)
            specialist = self._specialist_agents.get(classification.agent_type)

            if specialist is None:
                return SubagentOutput(
                    summary=f"No specialist available for type {classification.agent_type}",
                    confidence=0.0,
                    requires_human_review=True,
                    obstacles=[f"Specialist missing for {classification.agent_type}"],
                )

            logger.info(
                "Router dispatched %s to %s specialist",
                classification.agent_type, specialist,
            )

            return await specialist.invoke(input_data)

        except Exception as e:
            logger.error("Router execution failed: %s", e, exc_info=True)
            return SubagentOutput(
                summary=f"Router error: {e!s}",
                confidence=0.0,
                requires_human_review=True,
                obstacles=[f"Router failure: {e!s}"],
            )

    def _classify_input(self, input_data: dict[str, Any]) -> RouterClassification:
        """Classify input and determine which specialist to route to.

        In a real implementation, this would call the router model
        (e.g., cheap GPT-4o-mini) to classify the input and select
        the most appropriate specialist.
        """
        # Simple heuristic: route based on input type for demonstration
        content = str(input_data.get("content", "")).lower()

        if any(word in content for word in ["code", "function", "class", "programming"]):
            return RouterClassification(
                agent_type="coder",
                specialty="software-development",
                confidence=0.85,
                reason="Content contains programming keywords",
            )
        elif any(word in content for word in ["research", "search", "web", "information"]):
            return RouterClassification(
                agent_type="researcher",
                specialty="web-intelligence",
                confidence=0.90,
                reason="Content requires research or web search",
            )
        elif any(word in content for word in ["analyze", "analysis", "evaluate", "review"]):
            return RouterClassification(
                agent_type="evaluator",
                specialty="quality-assessment",
                confidence=0.80,
                reason="Content requires analysis or evaluation",
            )
        else:
            return RouterClassification(
                agent_type="coordinator",
                specialty="general-purpose",
                confidence=0.60,
                reason="General task, dispatching to coordinator",
            )