from datetime import datetime
from typing import Any

from pydantic import BaseModel, Field


class AgentCreate(BaseModel):
    name: str
    role: str
    description: str | None = None
    system_prompt: str
    spawn_permission: bool = False


class AgentOut(BaseModel):
    id: str
    name: str
    role: str
    description: str | None
    is_active: bool
    is_default: bool

    model_config = {"from_attributes": True}


class AgentMessageOut(BaseModel):
    id: str
    agent_id: str
    conversation_id: str
    role: str
    content: str

    model_config = {"from_attributes": True}


class AgentStats(BaseModel):
    agent_id: str
    call_count: int
    current_task: str | None
    status: str  # active | idle | disabled


class AgentConfigUpdate(BaseModel):
    name: str | None = None
    description: str | None = None
    system_prompt: str | None = None
    enabled: bool | None = None
    selected_skill_ids: list[str] | None = None


class AgentConfigOut(BaseModel):
    id: str
    name: str
    role: str
    description: str | None
    system_prompt: str
    enabled: bool
    is_active: bool
    selected_skill_ids: list[str]

    model_config = {"from_attributes": True}


class AgentVisibilityEventOut(BaseModel):
    event_id: str
    event_type: str
    timestamp: datetime
    conversation_id: str | None = None
    agent_id: str | None = None
    sub_commander_id: str | None = None
    task_id: str | None = None
    parent_task_id: str | None = None
    child_task_id: str | None = None
    thread_id: str | None = None
    message_id: str | None = None
    interrupt_id: str | None = None
    recovery_id: str | None = None
    payload: dict[str, Any] = Field(default_factory=dict)
    severity: str = "info"


class AgentVisibilityEventsResponse(BaseModel):
    conversation_id: str
    total: int
    limit: int
    offset: int
    items: list[AgentVisibilityEventOut]


class AgentVisibilityTaskSummaryOut(BaseModel):
    task_id: str
    role: str | None = None
    owner_agent_id: str | None = None
    status: str | None = None
    summary: str | None = None
    evidence_count: int = 0


class AgentVisibilityTopologyNodeOut(BaseModel):
    agent_id: str
    role: str | None = None
    parent_agent_id: str | None = None
    source: str
    task_count: int = 0
    completed_task_count: int = 0


class AgentVisibilityTopologyOut(BaseModel):
    conversation_id: str
    root_agent_id: str | None = None
    current_agent: str | None = None
    nodes: list[AgentVisibilityTopologyNodeOut]
    edges: list[dict[str, str]]
    tasks: list[AgentVisibilityTaskSummaryOut]
    task_hierarchy: dict[str, list[str]] = Field(default_factory=dict)


class AgentVisibilityEvidenceOut(BaseModel):
    conversation_id: str
    task_id: str
    task: dict[str, Any] | None = None
    result: dict[str, Any] | None = None
    tool_outcomes: list[dict[str, Any]] = Field(default_factory=list)
    verifier: dict[str, Any]


class AgentVisibilityThreadMessageOut(BaseModel):
    message_id: str
    thread_id: str
    from_agent_id: str
    to_agent_id: str
    task_id: str | None = None
    reply_to_message_id: str | None = None
    message_type: str
    content_summary: str
    created_at: datetime
    payload: dict[str, Any] = Field(default_factory=dict)


class AgentVisibilityThreadOut(BaseModel):
    conversation_id: str
    thread_id: str
    total: int
    items: list[AgentVisibilityThreadMessageOut]


class AgentVisibilityVerifierOut(BaseModel):
    conversation_id: str
    status: str | None = None
    summary: str | None = None
    evidence: list[dict[str, Any]] = Field(default_factory=list)


class AgentVisibilityIsolationOut(BaseModel):
    mode: str = "none"
    isolation_id: str | None = None
    workspace_path: str | None = None
    parent_conversation_id: str | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class AgentVisibilityCostOut(BaseModel):
    input_tokens: int = 0
    output_tokens: int = 0
    total_tokens: int = 0
    estimated_cost: float | None = None
    budget_warning: bool = False
    currency: str = "USD"


class AgentVisibilityCostByAgentOut(BaseModel):
    agent_id: str
    input_tokens: int = 0
    output_tokens: int = 0
    total_tokens: int = 0
    estimated_cost: float | None = None
    budget_warning: bool = False


class AgentVisibilityCostSummaryOut(BaseModel):
    conversation_id: str
    total: AgentVisibilityCostOut
    thresholds: dict[str, float] = Field(default_factory=dict)
    by_agent: list[AgentVisibilityCostByAgentOut] = Field(default_factory=list)


class AgentVisibilityToolGovernanceItemOut(BaseModel):
    capability_id: str
    tool_name: str
    permission_class: str
    side_effect_scope: str
    supports_retry: bool = False
    idempotent: bool = False
    safe_for_parallel_use: bool = False
    requires_confirmation: bool = False
    usage_count: int = 0
    last_result_preview: str | None = None


class AgentVisibilityToolGovernanceOut(BaseModel):
    conversation_id: str
    total_tools: int = 0
    used_tools: int = 0
    items: list[AgentVisibilityToolGovernanceItemOut] = Field(default_factory=list)
    upgrade_candidates: list[str] = Field(default_factory=list)


class AgentVisibilityRuntimeSummaryOut(BaseModel):
    conversation_id: str
    execution_mode: str | None = None
    current_phase: str | None = None
    current_checkpoint: str | None = None
    phase_history: list[dict[str, Any]] = Field(default_factory=list)
    checkpoint_history: list[dict[str, Any]] = Field(default_factory=list)
    verifier: AgentVisibilityVerifierOut
    isolation: AgentVisibilityIsolationOut
    cost: AgentVisibilityCostOut
    topology_node_count: int = 0
    active_task_count: int = 0
    completed_task_count: int = 0
    recent_events: list[AgentVisibilityEventOut] = Field(default_factory=list)
