"""
Execution Models
"""

from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Literal, Optional

from pydantic import BaseModel, Field


class ExecutionStatus(str, Enum):
    """Execution status."""
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


class StepStatus(str, Enum):
    """Step execution status."""
    PENDING = "pending"
    RUNNING = "running"
    PASSED = "passed"
    FAILED = "failed"
    SKIPPED = "skipped"


class ExecutionRequest(BaseModel):
    """Request to start execution."""
    project_id: str
    group_id: Optional[str] = None
    case_id: Optional[str] = None
    variables: Optional[Dict[str, Any]] = None  # Override variables


class ExecutionResponse(BaseModel):
    """Execution response."""
    execution_id: str
    status: ExecutionStatus
    message: str
    started_at: Optional[str] = None


class StepResult(BaseModel):
    """Result of a single step execution."""
    step_index: int
    step_name: str
    status: StepStatus
    started_at: Optional[str] = None
    completed_at: Optional[str] = None
    duration_ms: Optional[int] = None
    screenshot_ref: Optional[str] = None  # Reference to in-memory screenshot
    output: Optional[str] = None  # stdout, stderr, or error message
    error: Optional[str] = None


class TestResult(BaseModel):
    """Result of a test case execution."""
    case_id: str
    case_name: str
    status: ExecutionStatus
    started_at: str
    completed_at: Optional[str] = None
    duration_ms: Optional[int] = None
    steps: List[StepResult] = Field(default_factory=list)


class ExecutionEvent(BaseModel):
    """Real-time execution event (for WebSocket)."""
    type: Literal["start", "step_start", "step_complete", "complete", "error"]
    execution_id: str
    timestamp: str
    data: Dict[str, Any] = Field(default_factory=dict)


class FailureReport(BaseModel):
    """Failure report for AI coding tools."""
    context: Dict[str, str] = Field(..., description="Project/Case context")

    executed_steps: List[Dict[str, Any]] = Field(
        default_factory=list,
        description="Steps executed before failure"
    )

    failure: Dict[str, Any] = Field(
        ...,
        description="Failure details"
    )

    def to_natural_language(self) -> str:
        """Convert failure report to natural language for AI consumption."""
        steps_text = "\n".join([
            f"  {i+1}. {step.get('name', f'Step {i+1}')}"
            for i, step in enumerate(self.executed_steps)
        ])

        return f"""在执行测试用例 "{self.context.get('case_name', 'Unknown')}" 时失败。

已执行操作：
{steps_text}

失败位置：第 {self.failure.get('step_index', '?')} 步
尝试操作：{self.failure.get('attempted_action', 'Unknown')}

实际现象：
{self.failure.get('phenomenon', 'Unknown')}

预期结果：
{self.failure.get('expectation', 'Unknown')}
"""
