"""
Subagent Support

Subagents can be invoked by primary agents for specialized tasks.
Subagents inherit parent permissions or have stricter permissions.
"""

import time
from pathlib import Path
from typing import Any, Optional

from groknroll.agents.base_agent import AgentCapability, AgentConfig, AgentResponse, BaseAgent
from groknroll.core.rlm_integration import RLMConfig, RLMIntegration


class Subagent(BaseAgent):
    """
    Subagent - Can be invoked by other agents

    Subagents inherit parent agent permissions (or stricter).
    Used for delegating specialized tasks.

    Example:
        # Create subagent for research
        research_agent = Subagent(
            name="research",
            description="Research specialist",
            capabilities=[AgentCapability.READ_FILES, AgentCapability.SEARCH_CODE],
            project_path=Path("."),
        )

        # Invoke from parent agent
        result = parent.invoke_subagent(research_agent, "Research authentication patterns")
    """

    def __init__(
        self,
        name: str,
        description: str,
        capabilities: list[AgentCapability],
        project_path: Path,
        model: str = "gpt-4o-mini",
        max_cost: float = 2.0,  # Lower default cost for subagents
        timeout: int = 180,  # Shorter default timeout
    ):
        """
        Initialize subagent

        Args:
            name: Subagent name
            description: Subagent description
            capabilities: List of capabilities (should be subset of parent)
            project_path: Project root path
            model: LLM model to use
            max_cost: Maximum cost per execution
            timeout: Timeout in seconds
        """
        config = AgentConfig(
            name=name,
            description=description,
            capabilities=capabilities,
            model=model,
            max_cost=max_cost,
            timeout=timeout,
        )

        super().__init__(config, project_path)

        # Initialize RLM
        rlm_config = RLMConfig(model=model, max_cost=max_cost, timeout_seconds=timeout)
        self.rlm = RLMIntegration(rlm_config)

    def execute(self, task: str, context: Optional[dict[str, Any]] = None) -> AgentResponse:
        """
        Execute subagent task

        Args:
            task: Task description
            context: Additional context from parent

        Returns:
            AgentResponse
        """
        start_time = time.time()

        try:
            # Prepare context
            exec_context = {
                "agent": self.config.name,
                "agent_type": "subagent",
                "capabilities": self.get_capabilities(),
                "project_path": str(self.project_path),
                **(context or {}),
            }

            # Add instructions for subagent
            enhanced_task = f"""Task: {task}

You are a SUBAGENT named "{self.config.name}".

Description: {self.config.description}

Capabilities: {', '.join(self.get_capabilities())}

You were invoked by a parent agent to perform a specialized task.
Complete the task and return results to the parent agent.

Execute the task within your capabilities.
"""

            # Execute with RLM
            result = self.rlm.complete(task=enhanced_task, context=exec_context)

            elapsed_time = time.time() - start_time

            response = AgentResponse(
                success=result.success,
                message=result.response if result.success else result.error or "Unknown error",
                agent_name=self.config.name,
                task=task,
                cost=result.total_cost,
                time=elapsed_time,
                metadata={
                    "iterations": result.iterations,
                    "rlm_success": result.success,
                    "agent_type": "subagent",
                },
            )

            self._log_execution(response)
            return response

        except Exception as e:
            elapsed_time = time.time() - start_time

            response = AgentResponse(
                success=False,
                message=f"Subagent error: {e}",
                agent_name=self.config.name,
                task=task,
                time=elapsed_time,
            )

            self._log_execution(response)
            return response


# Add invoke methods to BaseAgent
def invoke_subagent(
    self: BaseAgent,
    subagent: "Subagent",
    task: str,
    context: Optional[dict[str, Any]] = None,
) -> str:
    """
    Invoke subagent to perform specialized task

    Args:
        subagent: Subagent instance to invoke
        task: Task description for subagent
        context: Additional context to pass

    Returns:
        Subagent response message

    Raises:
        PermissionError: If subagent has capabilities parent doesn't have
        RuntimeError: If subagent execution fails
    """
    # Validate subagent doesn't have more permissions than parent
    for cap in subagent.config.capabilities:
        if not self.can(cap):
            raise PermissionError(
                f"Subagent '{subagent.config.name}' has capability '{cap.value}' "
                f"that parent agent '{self.config.name}' does not have"
            )

    # Prepare context with parent info
    invoke_context = {
        "parent_agent": self.config.name,
        "parent_capabilities": self.get_capabilities(),
        **(context or {}),
    }

    # Execute subagent
    response = subagent.execute(task, invoke_context)

    # Log in parent's history
    self._log_execution(
        AgentResponse(
            success=response.success,
            message=f"Subagent '{subagent.config.name}': {response.message}",
            agent_name=self.config.name,
            task=f"Invoked subagent for: {task}",
            cost=response.cost,
            time=response.time,
            metadata={
                "subagent": subagent.config.name,
                "subagent_success": response.success,
            },
        )
    )

    if not response.success:
        raise RuntimeError(f"Subagent execution failed: {response.message}")

    return response.message


# Monkey-patch BaseAgent to add invoke_subagent method
BaseAgent.invoke_subagent = invoke_subagent
