from __future__ import annotations

from datetime import datetime, timezone
from enum import Enum
from typing import Any, Literal
from uuid import uuid4

from pydantic import BaseModel, Field


TaskLifecycleStatus = Literal["pending", "in_progress", "completed", "failed", "blocked"]
VerificationStatus = Literal["passed", "failed", "skipped"]
TaskResultStatus = Literal["completed", "failed", "blocked", "passed", "skipped"]
InterruptStatus = Literal["requested", "acknowledged", "resolved"]
BudgetMode = Literal["direct", "collaboration"]


class CodeProviderType(str, Enum):
    CLAUDE = "claude"
    GEMINI = "gemini"
    CODEX = "codex"
    OPENCODE = "opencode"


class RiskLevelType(str, Enum):
    LOW = "low"
    HIGH = "high"


class InterruptRecord(BaseModel):
    interrupt_id: str
    reason: str
    status: InterruptStatus = "requested"
    requested_by: str | None = None
    source_event_id: str | None = None
    requested_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    payload: dict[str, Any] = Field(default_factory=dict)


class RecoveryRecord(BaseModel):
    recovery_id: str
    source_interrupt_id: str | None = None
    strategy: str | None = None
    resumed_from_task_id: str | None = None
    resumed_from_thread_id: str | None = None
    recovered_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    payload: dict[str, Any] = Field(default_factory=dict)


class CollaborationBudget(BaseModel):
    mode: BudgetMode = "direct"
    max_parallel_tasks: int | None = None
    remaining_parallel_tasks: int | None = None
    max_tool_calls: int | None = None
    remaining_tool_calls: int | None = None
    max_iterations: int | None = None
    remaining_iterations: int | None = None
    escalation_threshold: int | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class AgentTask(BaseModel):
    task_id: str
    title: str
    status: TaskLifecycleStatus = "pending"
    owner_agent_id: str | None = None
    role: str | None = None
    goal: str | None = None
    parent_task_id: str | None = None
    child_task_ids: list[str] = Field(default_factory=list)
    thread_id: str | None = None
    message_id: str | None = None
    message_index: int | None = None
    expected_evidence: list[dict[str, Any]] = Field(default_factory=list)
    evidence: list[dict[str, Any]] = Field(default_factory=list)
    interrupt_records: list[InterruptRecord | dict[str, Any]] = Field(default_factory=list)
    recovery_records: list[RecoveryRecord | dict[str, Any]] = Field(default_factory=list)
    collaboration_budget: CollaborationBudget | dict[str, Any] | None = None
    result_summary: str | None = None
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
    updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))


class TaskResult(BaseModel):
    task_id: str
    status: TaskResultStatus
    summary: str | None = None
    evidence: list[dict[str, Any]] = Field(default_factory=list)
    owner_agent_id: str | None = None
    parent_task_id: str | None = None
    child_task_ids: list[str] = Field(default_factory=list)
    thread_id: str | None = None
    message_id: str | None = None
    message_index: int | None = None
    interrupt_records: list[InterruptRecord | dict[str, Any]] = Field(default_factory=list)
    recovery_records: list[RecoveryRecord | dict[str, Any]] = Field(default_factory=list)
    budget_snapshot: CollaborationBudget | dict[str, Any] | None = None
    next_action: str | None = None
    output_data: dict[str, Any] | None = None


class CodeTaskType(str, Enum):
    DEMO = "demo"
    PROJECT = "project"
    MODIFICATION = "modification"


class CodeTask(BaseModel):
    """代码任务请求模型"""

    task_id: str = Field(default_factory=lambda: str(uuid4()))
    task_type: CodeTaskType
    ai_provider: CodeProviderType
    sandbox_mode: bool = False
    workspace_path: str | None = None
    user_prompt: str
    parent_task_id: str | None = None
    thread_id: str | None = None
    message_id: str | None = None
    created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))


class CodeExecutionResultSchema(BaseModel):
    """代码执行结果模型 (API 响应用)"""

    success: bool
    message: str
    files_created: list[str] = Field(default_factory=list)
    output: str = ""
    error: str | None = None
    exit_code: int = 0
    execution_time: float | None = None
    sandbox_session_id: str | None = None
