"""
Pydantic Schemas for API Request/Response Validation
RULE: Data does not enter or leave the system without a visa (validation).
"""
from pydantic import BaseModel, Field, ConfigDict
from datetime import datetime
from uuid import UUID
from typing import Literal, Optional
from app.models import FactCategory


# ============================================================================
# INGESTION (Writing Memory)
# ============================================================================

class IngestRequest(BaseModel):
    """Request to ingest a chat message"""
    user_id: UUID
    session_id: UUID
    role: Literal["user", "assistant"]
    content: str = Field(..., min_length=1, description="The raw message content")


class IngestResponse(BaseModel):
    """Response after ingesting a message"""
    status: str = "queued"
    job_id: str | None = None
    chat_log_id: UUID


# ============================================================================
# RECALL (Reading Memory)
# ============================================================================

class RecallRequest(BaseModel):
    """Request to recall memory facts"""
    user_id: UUID
    query: str = Field(..., min_length=1, description="Current user input to search against")
    limit: int = Field(default=5, ge=1, le=20)
    categories: list[str] | None = Field(default=None, description="Optional categories to filter (biographical, work_context, user_preference, relationship, learning)")
    max_age_days: int | None = Field(default=None, description="Only return facts newer than this many days")
    current_view_only: bool = Field(default=True, description="If true, suppress superseded facts and show only current/active (default: true)")
    include_historical: bool = Field(default=False, description="If true, include past/historical facts; otherwise only return current/future/recurring facts")


class FactDTO(BaseModel):
    """Data Transfer Object for a Memory Fact"""
    category: str
    content: str
    confidence: float
    temporal_state: str = "current"  # current, past, future, recurring
    
    model_config = ConfigDict(from_attributes=True)


class RecallResponse(BaseModel):
    """Response containing relevant memory facts"""
    relevant_facts: list[FactDTO]


# ============================================================================
# SESSION MANAGEMENT
# ============================================================================

class UserCreate(BaseModel):
    """Request to create a new user"""
    pass


class UserResponse(BaseModel):
    id: UUID
    api_key: str


class SessionCreate(BaseModel):
    """Request to create a new session"""
    user_id: UUID


class SessionResponse(BaseModel):
    """Response with session details"""
    id: UUID
    user_id: UUID
    created_at: datetime
    
    model_config = ConfigDict(from_attributes=True)


# ============================================================================
# HISTORY
# ============================================================================

class ChatLogResponse(BaseModel):
    """Individual chat log in history"""
    id: UUID
    session_id: UUID
    role: str
    content: str
    timestamp: datetime
    
    model_config = ConfigDict(from_attributes=True)


class HistoryResponse(BaseModel):
    """Response containing chat history"""
    messages: list[ChatLogResponse]
    session_id: UUID


# ============================================================================
# FACTS
# ============================================================================

class FactWithId(BaseModel):
    """Fact DTO with full metadata for list endpoint."""
    id: UUID
    category: str
    content: str
    confidence: float
    is_essential: bool
    created_at: datetime
    source_message_id: UUID | None = None
    temporal_state: str | None = None
    
    model_config = ConfigDict(from_attributes=True)


class FactsListResponse(BaseModel):
    """Response for listing facts."""
    facts: list[FactWithId]


class FactSourceResponse(BaseModel):
    """Response including source message for a fact."""
    fact_id: UUID
    source_message_id: UUID | None
    session_id: UUID | None
    role: str | None
    content: str | None
    content_preview: str | None
    timestamp: datetime | None
