from datetime import datetime
from typing import Optional

from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, String
from sqlalchemy.orm import Mapped, mapped_column

from synthetic_agents.database.entity.base import Base


class ApplicationMessage(Base):
    """
    This class represents a message in an application.
    """

    __tablename__ = "application_message"
    __table_args__ = {
        "comment": "This table stores messages produced by the agents during an application."
    }

    message_id: Mapped[str] = mapped_column(
        "message_id",
        String,
        primary_key=True,
        comment="ID representing the message in the application.",
    )
    application_id: Mapped[int] = mapped_column(
        "application_id",
        Integer,
        ForeignKey("application.application_id"),
        comment="ID of the application.",
    )
    session_id: Mapped[str] = mapped_column(
        "session_id",
        String,
        comment="ID of the session. Messages can be collected for the same application in "
        "different sessions.",
    )
    message_number: Mapped[int] = mapped_column(
        "message_number",
        Integer,
        comment="Sequential number representing the message order in the session.",
    )
    agent_id: Mapped[int] = mapped_column(
        "agent_id",
        Integer,
        ForeignKey("agent.agent_id"),
        comment="ID of the agent that produced the message.",
    )
    started_at: Mapped[datetime] = mapped_column(
        "started_at", DateTime, comment="When the message started to be delivered."
    )
    finished_at: Mapped[datetime] = mapped_column(
        "finished_at", DateTime, comment="When the message was delivered."
    )
    message: Mapped[str] = mapped_column(
        "message", String, comment="Textual content of the message."
    )
    prompt: Mapped[str] = mapped_column(
        "prompt", String, comment="Prompt used by the LM to generate the message."
    )
    flagged: Mapped[bool] = mapped_column(
        "flagged", Boolean, comment="Flag indicating if the message was reported."
    )
    flagging_comment: Mapped[Optional[str]] = mapped_column(
        "flagging_comment", String, comment="Reasons behind why the message was flagged."
    )
