"""
EvenAge decorators for agents and tools.

Provides:
- @actor: Decorator for agent classes
- @tool: Decorator for tool functions (imported from tooling.py)
"""

from __future__ import annotations

from collections.abc import Callable
from typing import TypeVar

from .agent_runtime import Agent


T = TypeVar("T", bound=type[Agent])


def actor(
    name: str | None = None,
    role: str | None = None,
    goal: str | None = None,
    backstory: str | None = None,
    allow_delegation: bool = True,
    max_iterations: int = 25,
    tools: list | None = None
) -> Callable[[T], T]:
    """
    Decorator to mark a class as an EvenAge actor (agent).
    
    Sets class-level metadata for the agent and validates it's a subclass of Agent.
    
    Usage:
        @actor(
            name="researcher",
            role="Research Specialist",
            goal="Find accurate information on any topic",
            tools=[web_search.run]
        )
        class ResearchAgent(Agent):
            pass  # Everything handled by the framework!
    
    Args:
        name: Agent name (defaults to lowercase class name)
        role: Agent role description
        goal: Agent goal description
        backstory: Agent backstory (optional)
        allow_delegation: Whether agent can delegate to others
        max_iterations: Maximum planning iterations
        tools: List of tool functions to bind to agent
    
    Returns:
        Decorated class with agent metadata
    """
    def decorator(cls: T) -> T:
        # Validate it's a subclass of Agent
        if not issubclass(cls, Agent):
            raise TypeError(f"@actor can only be applied to Agent subclasses, got {cls}")

        # Set class-level metadata
        agent_name = name or cls.__name__.lower()
        cls.AGENT_NAME = agent_name
        cls.ROLE = role or cls.ROLE
        cls.GOAL = goal or cls.GOAL
        cls.BACKSTORY = backstory or getattr(cls, "BACKSTORY", "")
        cls.ALLOW_DELEGATION = allow_delegation
        cls.MAX_ITERATIONS = max_iterations
        cls.TOOLS = tools or []

        # Mark as actor
        cls.__evenage_actor__ = True
        
        # If tools are provided, override __init__ to bind them automatically
        if tools:
            original_init = cls.__init__
            
            def new_init(self, config, env_config=None):
                # Call original init
                if original_init is not Agent.__init__:
                    original_init(self, config, env_config)
                else:
                    Agent.__init__(self, config, env_config)
                
                # Bind tools from decorator
                from .tooling import bind_tools
                bind_tools(self, cls.TOOLS)
            
            cls.__init__ = new_init

        return cls

    return decorator


# Re-export tool decorator from tooling
from .tooling import tool


__all__ = ["actor", "tool"]
