"""Core types for CAMEL framework."""

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional
import uuid


class AgentType(Enum):
    """Types of agents in CAMEL."""
    ASSISTANT = "assistant"
    USER = "user"
    CRITIC = "critic"
    EXPERT = "expert"


@dataclass
class Role:
    """Defines the role of an agent."""
    name: str
    description: str
    agent_type: AgentType = AgentType.ASSISTANT
    role_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])

    def get_system_prompt(self) -> str:
        """Generate system prompt for this role."""
        return f"You are a {self.name}. {self.description}"

    def to_dict(self) -> Dict[str, Any]:
        return {
            "role_id": self.role_id,
            "name": self.name,
            "description": self.description,
            "agent_type": self.agent_type.value,
        }


@dataclass
class Task:
    """A task for agents to collaborate on."""
    description: str
    task_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
    metadata: Dict[str, Any] = field(default_factory=dict)
    created_at: datetime = field(default_factory=datetime.now)

    def to_dict(self) -> Dict[str, Any]:
        return {
            "task_id": self.task_id,
            "description": self.description,
            "metadata": self.metadata,
            "created_at": self.created_at.isoformat(),
        }


@dataclass
class TaskSpec:
    """Specification for a collaborative task."""
    original_task: str
    roles: List[Role] = field(default_factory=list)
    max_turns: int = 10
    success_criteria: Optional[str] = None

    def get_inception_prompt(self, role: Role, other_role: Role) -> str:
        """Generate inception prompt for role-playing.

        Args:
            role: The role receiving the prompt
            other_role: The other role in the conversation

        Returns:
            Inception prompt string
        """
        prompt = f"""You are {role.name}. {role.description}

You are collaborating with {other_role.name}, who is {other_role.description}

Your joint task is: {self.original_task}

Remember:
1. Stay in character as {role.name}
2. Work collaboratively with {other_role.name}
3. Focus on completing the task
4. Be concise but thorough

Begin by introducing yourself and your approach to the task."""
        return prompt

    def to_dict(self) -> Dict[str, Any]:
        return {
            "original_task": self.original_task,
            "roles": [r.to_dict() for r in self.roles],
            "max_turns": self.max_turns,
            "success_criteria": self.success_criteria,
        }


# Predefined roles for common scenarios
DEFAULT_ROLES = {
    "programmer": Role(
        name="Python Programmer",
        description="You are an expert Python programmer who writes clean, efficient code.",
        agent_type=AgentType.ASSISTANT,
    ),
    "reviewer": Role(
        name="Code Reviewer",
        description="You are a meticulous code reviewer who ensures quality and best practices.",
        agent_type=AgentType.USER,
    ),
    "teacher": Role(
        name="Teacher",
        description="You are an experienced educator who explains concepts clearly.",
        agent_type=AgentType.ASSISTANT,
    ),
    "student": Role(
        name="Student",
        description="You are an eager learner who asks thoughtful questions.",
        agent_type=AgentType.USER,
    ),
    "writer": Role(
        name="Content Writer",
        description="You are a skilled writer who creates engaging content.",
        agent_type=AgentType.ASSISTANT,
    ),
    "editor": Role(
        name="Editor",
        description="You are a detail-oriented editor who improves text quality.",
        agent_type=AgentType.USER,
    ),
}