"""
Web API Types - Data models for the web interface

Defines Pydantic models for API requests and responses.
"""

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

from pydantic import BaseModel, Field


class MessageRole(str, Enum):
    """Role of a message in the conversation"""

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


class AgentType(str, Enum):
    """Available agent types"""

    BUILD = "build"
    PLAN = "plan"
    ORACLE = "oracle"
    CUSTOM = "custom"


class SessionStatus(str, Enum):
    """Session status"""

    ACTIVE = "active"
    COMPLETED = "completed"
    ERROR = "error"


# Request Models
class ChatRequest(BaseModel):
    """Request for chat completion"""

    message: str = Field(..., description="User message")
    session_id: Optional[str] = Field(None, description="Session ID to continue")
    agent: AgentType = Field(AgentType.BUILD, description="Agent to use")
    stream: bool = Field(True, description="Stream responses")
    files: list[str] = Field(default_factory=list, description="Referenced files (@file)")


class ToolCallRequest(BaseModel):
    """Request to call a specific tool"""

    tool: str = Field(..., description="Tool name")
    arguments: dict[str, Any] = Field(default_factory=dict, description="Tool arguments")
    session_id: Optional[str] = Field(None, description="Session ID")


class SessionCreateRequest(BaseModel):
    """Request to create a new session"""

    name: Optional[str] = Field(None, description="Session name")
    agent: AgentType = Field(AgentType.BUILD, description="Default agent")


class SessionExportRequest(BaseModel):
    """Request to export a session"""

    format: str = Field("markdown", description="Export format (markdown, json)")


# Response Models
class Message(BaseModel):
    """A single message in the conversation"""

    role: MessageRole
    content: str
    timestamp: datetime = Field(default_factory=datetime.now)
    tool_calls: Optional[list[dict[str, Any]]] = None
    tool_results: Optional[list[dict[str, Any]]] = None


class ToolInfo(BaseModel):
    """Information about a tool"""

    name: str
    description: str
    parameters: dict[str, Any] = Field(default_factory=dict)


class ToolCallResult(BaseModel):
    """Result from a tool call"""

    tool: str
    success: bool
    result: Any
    error: Optional[str] = None
    duration_ms: int = 0


class SessionInfo(BaseModel):
    """Information about a session"""

    id: str
    name: Optional[str] = None
    agent: AgentType
    status: SessionStatus
    created_at: datetime
    updated_at: datetime
    message_count: int = 0


class SessionDetail(SessionInfo):
    """Detailed session information with messages"""

    messages: list[Message] = Field(default_factory=list)


class ChatResponse(BaseModel):
    """Response from chat completion"""

    session_id: str
    message: Message
    done: bool = True


class StreamChunk(BaseModel):
    """A chunk of streamed response"""

    session_id: str
    type: str = "text"  # text, tool_call, tool_result, done, error
    content: str = ""
    tool_call: Optional[dict[str, Any]] = None
    tool_result: Optional[dict[str, Any]] = None


class ErrorResponse(BaseModel):
    """Error response"""

    error: str
    code: str = "ERROR"
    details: Optional[dict[str, Any]] = None


class HealthResponse(BaseModel):
    """Health check response"""

    status: str = "ok"
    version: str
    uptime_seconds: float


class ProviderInfo(BaseModel):
    """Information about a configured provider"""

    name: str
    display_name: str
    enabled: bool
    models: list[str] = Field(default_factory=list)


class ModelInfo(BaseModel):
    """Information about an available model"""

    id: str
    name: str
    provider: str
    context_length: Optional[int] = None
    cost_per_1k_input: Optional[float] = None
    cost_per_1k_output: Optional[float] = None


class StatsResponse(BaseModel):
    """Usage statistics"""

    total_sessions: int
    total_messages: int
    total_cost: float
    total_tokens: int
    average_response_time_ms: float
