"""Data models for web chat."""

from __future__ import annotations

from datetime import datetime, timezone
from enum import Enum
from typing import Any

from pydantic import BaseModel, ConfigDict, Field


class MessageRole(str, Enum):
    """Message roles in chat."""

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


class ChatMessage(BaseModel):
    """A chat message."""

    model_config = ConfigDict(
        json_encoders={
            datetime: lambda v: v.isoformat(),
        }
    )

    id: str = Field(..., description="Unique message ID")
    role: MessageRole = Field(..., description="Message role")
    content: str = Field(..., description="Message content")
    timestamp: datetime = Field(
        default_factory=lambda: datetime.now(timezone.utc), description="Message timestamp"
    )
    metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata")


class ChatRequest(BaseModel):
    """Request to send a chat message."""

    content: str = Field(..., min_length=1, max_length=10000, description="Message content")
    conversation_id: str | None = Field(default=None, description="Optional conversation ID")


class ChatResponse(BaseModel):
    """Response from the assistant."""

    message: ChatMessage = Field(..., description="Assistant message")
    conversation_id: str = Field(..., description="Conversation ID")


class ConversationSummary(BaseModel):
    """Summary of a conversation."""

    id: str = Field(..., description="Conversation ID")
    title: str = Field(..., description="Conversation title")
    message_count: int = Field(..., description="Number of messages")
    created_at: datetime = Field(..., description="Creation timestamp")
    updated_at: datetime = Field(..., description="Last update timestamp")


class WebSocketMessage(BaseModel):
    """WebSocket message format."""

    type: str = Field(..., description="Message type: chat, typing, error, ping")
    data: dict[str, Any] = Field(default_factory=dict, description="Message data")
