"""
Conversation Context Type.

Represents conversation history for context continuity.
"""

from dataclasses import dataclass, field
from datetime import UTC, datetime
from enum import Enum
from typing import Any

from .base import BaseContext, ContextPriority, ContextType


class MessageRole(str, Enum):
    """Roles for conversation messages."""

    USER = "user"
    ASSISTANT = "assistant"
    SYSTEM = "system"
    TOOL = "tool"

    @classmethod
    def from_string(cls, value: str) -> "MessageRole":
        """Convert string to MessageRole."""
        try:
            return cls(value.lower())
        except ValueError:
            # Default to user for unknown roles
            return cls.USER


@dataclass(eq=False)
class ConversationContext(BaseContext):
    """
    Context from conversation history.

    Represents a single turn in the conversation,
    including user messages, assistant responses,
    and tool results.
    """

    # Conversation-specific fields
    role: MessageRole = field(default=MessageRole.USER)
    turn_index: int = field(default=0)
    session_id: str | None = field(default=None)
    parent_message_id: str | None = field(default=None)

    def get_type(self) -> ContextType:
        """Return CONVERSATION context type."""
        return ContextType.CONVERSATION

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary with conversation-specific fields."""
        base = super().to_dict()
        base.update(
            {
                "role": self.role.value,
                "turn_index": self.turn_index,
                "session_id": self.session_id,
                "parent_message_id": self.parent_message_id,
            }
        )
        return base

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> "ConversationContext":
        """Create ConversationContext from dictionary."""
        role = data.get("role", "user")
        if isinstance(role, str):
            role = MessageRole.from_string(role)

        return cls(
            id=data.get("id", ""),
            content=data["content"],
            source=data.get("source", "conversation"),
            timestamp=datetime.fromisoformat(data["timestamp"])
            if isinstance(data.get("timestamp"), str)
            else data.get("timestamp", datetime.now(UTC)),
            priority=data.get("priority", ContextPriority.NORMAL.value),
            metadata=data.get("metadata", {}),
            role=role,
            turn_index=data.get("turn_index", 0),
            session_id=data.get("session_id"),
            parent_message_id=data.get("parent_message_id"),
        )

    @classmethod
    def from_message(
        cls,
        content: str,
        role: str | MessageRole,
        turn_index: int = 0,
        session_id: str | None = None,
        timestamp: datetime | None = None,
    ) -> "ConversationContext":
        """
        Create ConversationContext from a message.

        Args:
            content: Message content
            role: Message role (user, assistant, system, tool)
            turn_index: Position in conversation
            session_id: Session identifier
            timestamp: Message timestamp

        Returns:
            ConversationContext instance
        """
        if isinstance(role, str):
            role = MessageRole.from_string(role)

        # Recent messages have higher priority
        priority = ContextPriority.NORMAL.value

        return cls(
            content=content,
            source="conversation",
            role=role,
            turn_index=turn_index,
            session_id=session_id,
            timestamp=timestamp or datetime.now(UTC),
            priority=priority,
        )

    @classmethod
    def from_history(
        cls,
        messages: list[dict[str, Any]],
        session_id: str | None = None,
    ) -> list["ConversationContext"]:
        """
        Create multiple ConversationContexts from message history.

        Args:
            messages: List of message dicts with 'role' and 'content'
            session_id: Session identifier

        Returns:
            List of ConversationContext instances
        """
        contexts = []
        for i, msg in enumerate(messages):
            ctx = cls.from_message(
                content=msg.get("content", ""),
                role=msg.get("role", "user"),
                turn_index=i,
                session_id=session_id,
                timestamp=datetime.fromisoformat(msg["timestamp"])
                if "timestamp" in msg
                else None,
            )
            contexts.append(ctx)
        return contexts

    def is_user_message(self) -> bool:
        """Check if this is a user message."""
        return self.role == MessageRole.USER

    def is_assistant_message(self) -> bool:
        """Check if this is an assistant message."""
        return self.role == MessageRole.ASSISTANT

    def is_tool_result(self) -> bool:
        """Check if this is a tool result."""
        return self.role == MessageRole.TOOL

    def format_for_prompt(self) -> str:
        """
        Format message for inclusion in prompt.

        Returns:
            Formatted message string
        """
        role_labels = {
            MessageRole.USER: "User",
            MessageRole.ASSISTANT: "Assistant",
            MessageRole.SYSTEM: "System",
            MessageRole.TOOL: "Tool Result",
        }
        label = role_labels.get(self.role, "Unknown")
        return f"{label}: {self.content}"
