"""Pydantic Schemas for Norm API"""
from datetime import datetime
from typing import Optional, List, Dict, Any
from uuid import UUID
from pydantic import BaseModel, Field, ConfigDict


# --- Norm Schemas ---

class NormScope(BaseModel):
    """Norm scope definition"""
    roles: List[str] = Field(default_factory=list, description="Applicable agent roles")
    contexts: List[str] = Field(default_factory=list, description="Applicable contexts")


class NormCondition(BaseModel):
    """Norm condition definition"""
    trigger: str = Field(..., description="Trigger event")
    preconditions: List[str] = Field(default_factory=list, description="Required preconditions")


class NormAction(BaseModel):
    """Norm action definition"""
    required: Optional[str] = Field(None, description="Required action")
    prohibited: List[str] = Field(default_factory=list, description="Prohibited actions")


class NormConsequence(BaseModel):
    """Norm consequence definition"""
    on_compliance: Optional[Dict[str, Any]] = Field(None, description="Reward for compliance")
    on_violation: Optional[Dict[str, Any]] = Field(None, description="Sanction for violation")


class NormCreate(BaseModel):
    """Schema for creating a new norm"""
    name: str = Field(..., min_length=1, max_length=255)
    norm_type: str = Field(..., description="obligation/prohibition/permission")
    authority_level: Optional[str] = Field(None, description="legal/industry/organizational")
    domain: Optional[str] = Field(None, description="Domain category")
    field_id: Optional[UUID] = Field(None, description="Information field ID")
    scope_roles: List[str] = Field(default_factory=list)
    scope_contexts: List[str] = Field(default_factory=list)
    condition: Dict[str, Any] = Field(default_factory=dict)
    action: Dict[str, Any] = Field(default_factory=dict)
    consequence: Dict[str, Any] = Field(default_factory=dict)
    formatted_prompt: Optional[str] = Field(None, description="LLM-readable prompt")
    source: Optional[str] = Field(None, description="Source document/policy (brief)")
    source_details: Optional[Dict[str, Any]] = Field(None, description="Detailed source information")
    
    case_refs: List[str] = Field(default_factory=list)
    
    status: str = Field("draft", description="draft/active/deprecated")
    created_by: Optional[str] = Field(None, description="Creator identifier")


class NormUpdate(BaseModel):
    """Schema for updating an existing norm"""
    name: Optional[str] = Field(None, min_length=1, max_length=255)
    norm_type: Optional[str] = None
    authority_level: Optional[str] = None
    domain: Optional[str] = None
    field_id: Optional[UUID] = None
    scope_roles: Optional[List[str]] = None
    scope_contexts: Optional[List[str]] = None
    condition: Optional[Dict[str, Any]] = None
    action: Optional[Dict[str, Any]] = None
    consequence: Optional[Dict[str, Any]] = None
    formatted_prompt: Optional[str] = None
    source: Optional[str] = None
    source_details: Optional[Dict[str, Any]] = None
    status: Optional[str] = Field(None, description="draft/active/deprecated")
    case_refs: Optional[List[str]] = None


class NormResponse(BaseModel):
    """Schema for norm response"""
    model_config = ConfigDict(from_attributes=True)
    
    id: UUID
    name: str
    norm_type: str
    authority_level: Optional[str] = None
    domain: Optional[str] = None
    field_id: Optional[UUID] = None  # Information field ID
    
    scope_roles: List[str]
    scope_contexts: List[str]
    
    condition: Dict[str, Any]
    action: Dict[str, Any]
    consequence: Dict[str, Any]
    
    formatted_prompt: Optional[str] = None
    source: Optional[str] = None
    source_details: Optional[Dict[str, Any]] = None
    version: int
    status: str
    
    case_refs: List[str]
    
    created_by: Optional[str] = None
    created_at: datetime
    updated_at: datetime


class NormListResponse(BaseModel):
    """Schema for norm list response"""
    total: int
    items: List[NormResponse]
    page: int = 1
    page_size: int = 20


# --- Norm Version Schemas ---

class NormVersionResponse(BaseModel):
    """Schema for norm version response"""
    model_config = ConfigDict(from_attributes=True)
    
    id: UUID
    norm_id: UUID
    version: int
    snapshot: Dict[str, Any]
    change_note: Optional[str] = None
    created_at: datetime


# --- Norm Relation Schemas ---

class NormRelationCreate(BaseModel):
    """Schema for creating norm relation"""
    target_norm_id: UUID
    relation_type: str  # conflicts_with/derives_from/supersedes/requires
    resolution: Optional[str] = None


class NormRelationResponse(BaseModel):
    """Schema for norm relation response"""
    model_config = ConfigDict(from_attributes=True)
    
    source_norm_id: UUID
    target_norm_id: UUID
    relation_type: str
    resolution: Optional[str] = None


# --- Retrieve Schemas ---

class NormRetrieveRequest(BaseModel):
    """Schema for norm retrieval request"""
    context: Dict[str, Any] = Field(default_factory=dict, description="Task context")
    agent_role: str = Field(..., description="Agent role")
    field_ids: Optional[List[UUID]] = Field(None, description="Information field IDs to search in")
    top_k: int = Field(5, ge=1, le=50, description="Number of norms to retrieve")


class NormRetrieveResponse(BaseModel):
    """Schema for norm retrieval response"""
    norms: List[NormResponse]
    scores: List[float]
    total: int
    cache_hit: bool = False


# --- Role Suggestion Schemas ---

class RoleCandidate(BaseModel):
    """One suggested role candidate for retrieval."""
    role: str
    score: float
    norm_count: int
    matched_contexts: List[str] = Field(default_factory=list)


class RoleSuggestRequest(BaseModel):
    """Schema for role suggestion request."""
    context: Dict[str, Any] = Field(default_factory=dict, description="Task context")
    field_ids: Optional[List[UUID]] = Field(None, description="Optional information field IDs")
    top_k: int = Field(5, ge=1, le=20, description="Number of candidate roles")


class RoleSuggestResponse(BaseModel):
    """Schema for role suggestion response."""
    candidates: List[RoleCandidate]
    recommended_role: Optional[str] = None
