
import uuid
from typing import Optional, Any
from pydantic import BaseModel, Field, field_validator, UUID4
from time import time

from gwenflow.types.message import Message
from gwenflow.types.usage import Usage
from gwenflow.types.output import ResponseOutputItem



class ModelResponse(BaseModel):

    id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
    """The id of the response."""

    content: Optional[str] = ""
    """The text content of the final response."""

    content_parsed: Optional[Any] = None
    """The parsed content of the final response."""

    finish_reason: Optional[str] = None
    """The finish reason of the response."""

    usage: Usage = Field(default_factory=Usage)
    """The usage information for the response."""

    created_at: int = Field(default_factory=lambda: int(time()))

    @field_validator("id", mode="before")
    @classmethod
    def deny_user_set_id(cls, v: Optional[UUID4]) -> None:
        if v:
            raise ValueError("This field is not to be set by the user.")

    def to_messages(self) -> list[Message]:
        """Convert the output into a list of input items suitable for passing to the model."""
        return [Message(**it.model_dump(exclude_unset=True)) for it in self.output]  # type: ignore



class AgentResponse(BaseModel):

    id: UUID4 = Field(default_factory=uuid.uuid4, frozen=True)
    """The id of the response."""

    content: Optional[str] = ""
    """The content of the final response."""

    thinking: Optional[str] = ""
    """The thinking of the response."""

    output: list[Message] = Field(default_factory=list)
    """A list of outputs (messages, tool calls, etc) generated by the agent."""

    sources: list[ResponseOutputItem] = Field(default_factory=list)
    """A list of sources."""

    finish_reason: Optional[str] = None
    """The finish reason of the response."""

    usage: Usage = Field(default_factory=Usage)
    """The usage information for the response."""

    created_at: int = Field(default_factory=lambda: int(time()))

    @field_validator("id", mode="before")
    @classmethod
    def deny_user_set_id(cls, v: Optional[UUID4]) -> None:
        if v:
            raise ValueError("This field is not to be set by the user.")

    def to_messages(self) -> list[Message]:
        """Convert the output into a list of input items suitable for passing to the model."""
        return [Message(**it.model_dump(exclude_unset=True)) for it in self.output]  # type: ignore
