"""
Pydantic схеми для Memory Service API
"""

from datetime import datetime
from typing import Optional, Dict, Any, List
from pydantic import BaseModel, Field, field_validator, ConfigDict
from uuid import UUID


# ========== User Facts Schemas ==========

class UserFactBase(BaseModel):
    """Базова схема для user fact"""
    fact_key: str = Field(..., description="Ключ факту (наприклад: 'language', 'is_donor')")
    fact_value: Optional[str] = Field(None, description="Текстове значення")
    fact_value_json: Optional[Dict[str, Any]] = Field(None, description="JSON значення")
    team_id: Optional[str] = Field(None, description="ID команди (якщо факт командно-специфічний)")
    meta: Dict[str, Any] = Field(default_factory=dict, description="Метадані")
    token_gated: bool = Field(False, description="Чи залежить факт від токенів")
    token_requirements: Optional[Dict[str, Any]] = Field(None, description="Вимоги до токенів")
    expires_at: Optional[datetime] = Field(None, description="Термін дії факту")


class UserFactCreate(UserFactBase):
    """Схема для створення/оновлення факту"""
    user_id: str = Field(..., description="ID користувача")


class UserFactUpdate(BaseModel):
    """Схема для часткового оновлення факту"""
    fact_value: Optional[str] = None
    fact_value_json: Optional[Dict[str, Any]] = None
    meta: Optional[Dict[str, Any]] = None
    token_gated: Optional[bool] = None
    token_requirements: Optional[Dict[str, Any]] = None
    expires_at: Optional[datetime] = None


class UserFactResponse(UserFactBase):
    """Схема відповіді для user fact"""
    id: str
    user_id: str
    created_at: datetime
    updated_at: Optional[datetime]

    model_config = ConfigDict(from_attributes=True)


class UserFactUpsertRequest(BaseModel):
    """Схема для upsert операції (створення або оновлення)"""
    user_id: str
    fact_key: str
    fact_value: Optional[str] = None
    fact_value_json: Optional[Dict[str, Any]] = None
    team_id: Optional[str] = None
    meta: Dict[str, Any] = Field(default_factory=dict)
    token_gated: bool = False
    token_requirements: Optional[Dict[str, Any]] = None
    expires_at: Optional[datetime] = None


class UserFactUpsertResponse(BaseModel):
    """Відповідь на upsert"""
    fact: UserFactResponse
    created: bool = Field(..., description="Чи був створений новий факт")


# ========== Dialog Summary Schemas ==========

class DialogSummaryBase(BaseModel):
    """Базова схема для dialog summary"""
    team_id: str
    channel_id: Optional[str] = None
    agent_id: Optional[str] = None
    user_id: Optional[str] = None
    period_start: datetime
    period_end: datetime
    summary_text: str
    summary_json: Optional[Dict[str, Any]] = None
    message_count: int = 0
    participant_count: int = 0
    topics: Optional[List[str]] = None
    meta: Dict[str, Any] = Field(default_factory=dict)


class DialogSummaryCreate(DialogSummaryBase):
    """Схема для створення summary"""
    pass


class DialogSummaryResponse(DialogSummaryBase):
    """Схема відповіді для summary"""
    id: str
    created_at: datetime

    model_config = ConfigDict(from_attributes=True)


class DialogSummaryListResponse(BaseModel):
    """Схема для списку summaries"""
    items: List[DialogSummaryResponse]
    total: int
    cursor: Optional[str] = None


# ========== Agent Memory Event Schemas ==========

class AgentMemoryEventBase(BaseModel):
    """Базова схема для memory event"""
    agent_id: str
    team_id: str
    channel_id: Optional[str] = None
    user_id: Optional[str] = None
    scope: str = Field(..., description="short_term | mid_term | long_term")
    kind: str = Field(..., description="message | fact | summary | note")
    body_text: Optional[str] = None
    body_json: Optional[Dict[str, Any]] = None

    @field_validator("scope")
    @classmethod
    def validate_scope(cls, v):
        if v not in ["short_term", "mid_term", "long_term"]:
            raise ValueError("scope must be one of: short_term, mid_term, long_term")
        return v

    @field_validator("kind")
    @classmethod
    def validate_kind(cls, v):
        if v not in ["message", "fact", "summary", "note"]:
            raise ValueError("kind must be one of: message, fact, summary, note")
        return v


class AgentMemoryEventCreate(AgentMemoryEventBase):
    """Схема для створення memory event"""
    pass


class AgentMemoryEventResponse(AgentMemoryEventBase):
    """Схема відповіді для memory event"""
    id: str
    created_at: datetime

    model_config = ConfigDict(from_attributes=True)


class AgentMemoryEventListResponse(BaseModel):
    """Схема для списку memory events"""
    items: List[AgentMemoryEventResponse]
    total: int
    cursor: Optional[str] = None


# ========== Token Gate Integration ==========

class TokenGateCheck(BaseModel):
    """Перевірка токен-гейту для факту"""
    user_id: str
    fact_key: str
    token_requirements: Dict[str, Any]


class TokenGateCheckResponse(BaseModel):
    """Відповідь на перевірку токен-гейту"""
    allowed: bool
    reason: Optional[str] = None
    missing_requirements: Optional[Dict[str, Any]] = None

