"""
Module defining the GeneratedAssistantMessage class representing messages
generated by an assistant with parsed content.
"""

from collections.abc import Sequence
from typing import Literal

from rsb.decorators.value_objects import valueobject
from rsb.models.base_model import BaseModel
from rsb.models.field import Field

from agentle.generations.models.message_parts.text import TextPart
from agentle.generations.models.message_parts.tool_execution_suggestion import (
    ToolExecutionSuggestion,
)
from agentle.generations.models.messages.assistant_message import AssistantMessage


@valueobject
class GeneratedAssistantMessage[T](BaseModel):
    """
    Represents a message generated by an assistant with parsed content.

    This class extends the concept of an assistant message with a parsed
    representation of the message content of type T. It supports generic typing
    to allow for different types of parsed content.
    """

    role: Literal["assistant"] = Field(
        default="assistant",
        description="Discriminator field to identify this as an assistant message. Always set to 'assistant'.",
    )

    parts: Sequence[TextPart | ToolExecutionSuggestion] = Field(
        description="The sequence of message parts that make up this generated assistant message.",
    )

    parsed: T = Field(
        description="The parsed representation of the message content of type T."
    )

    def to_assistant_message(self) -> AssistantMessage:
        return AssistantMessage(role="assistant", parts=self.parts)

    @property
    def tool_calls(self) -> Sequence[ToolExecutionSuggestion]:
        """
        Returns all tool execution suggestions contained in this message.

        Returns:
            Sequence[ToolExecutionSuggestion]: A sequence of tool execution suggestions.
        """
        return [
            part for part in self.parts if isinstance(part, ToolExecutionSuggestion)
        ]

    @property
    def text(self) -> str:
        """
        Returns the concatenated text representation of all parts in this message.

        Returns:
            str: The concatenated text of all message parts.
        """
        return "".join(
            part.text if isinstance(part.text, str) else part.text.text
            for part in self.parts
        )
