"""
Base Agent Interface

Defines the common interface for all groknroll agents.
"""

from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
from typing import Any, Optional


class AgentCapability(Enum):
    """Agent capabilities"""

    READ_FILES = "read_files"
    WRITE_FILES = "write_files"
    EDIT_FILES = "edit_files"
    DELETE_FILES = "delete_files"
    EXECUTE_BASH = "execute_bash"
    GIT_OPERATIONS = "git_operations"
    ANALYZE_CODE = "analyze_code"
    SEARCH_CODE = "search_code"


@dataclass
class AgentConfig:
    """Configuration for an agent"""

    name: str
    description: str
    capabilities: list[AgentCapability]
    model: str = "gpt-4o-mini"
    max_cost: float = 5.0
    timeout: int = 300
    verbose: bool = False


@dataclass
class AgentResponse:
    """Response from agent execution"""

    success: bool
    message: str
    agent_name: str
    task: str
    cost: float = 0.0
    time: float = 0.0
    metadata: Optional[dict[str, Any]] = None


class BaseAgent(ABC):
    """
    Base class for all groknroll agents

    Agents have different capabilities and permission levels.
    """

    def __init__(self, config: AgentConfig, project_path: Path):
        """
        Initialize agent

        Args:
            config: Agent configuration
            project_path: Project root path
        """
        self.config = config
        self.project_path = project_path
        self.execution_history: list[AgentResponse] = []

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

        Args:
            task: Task description
            context: Additional context

        Returns:
            AgentResponse
        """
        pass

    def can(self, capability: AgentCapability) -> bool:
        """Check if agent has capability"""
        return capability in self.config.capabilities

    def require(self, capability: AgentCapability) -> None:
        """Require capability (raises error if not available)"""
        if not self.can(capability):
            raise PermissionError(
                f"Agent '{self.config.name}' does not have capability: {capability.value}"
            )

    def get_capabilities(self) -> list[str]:
        """Get list of capability names"""
        return [cap.value for cap in self.config.capabilities]

    def get_stats(self) -> dict[str, Any]:
        """Get agent statistics"""
        successful = [r for r in self.execution_history if r.success]
        failed = [r for r in self.execution_history if not r.success]

        return {
            "name": self.config.name,
            "total_executions": len(self.execution_history),
            "successful": len(successful),
            "failed": len(failed),
            "total_cost": sum(r.cost for r in self.execution_history),
            "total_time": sum(r.time for r in self.execution_history),
            "capabilities": self.get_capabilities(),
        }

    def _log_execution(self, response: AgentResponse) -> None:
        """Log execution to history"""
        self.execution_history.append(response)

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}(name={self.config.name})"
