"""
Test Case Models
"""

from datetime import datetime
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field

from .project import ExecutionMode
from .dsl import TestStep, Assertion


class TestCase(BaseModel):
    """Test case model."""

    id: str = Field(..., description="Unique case identifier")
    name: str = Field(..., description="Case name")
    description: Optional[str] = Field(default=None, description="Case description")
    source: Optional[str] = Field(default=None, description="Source PRD paragraph reference")
    execution_mode: ExecutionMode = Field(default=ExecutionMode.SCREEN)
    # Allow both TestStep objects and raw dicts for flexibility with AI-generated YAML
    steps: List[Union[TestStep, Dict[str, Any]]] = Field(default_factory=list, description="Test steps")
    assertions: List[Assertion] = Field(default_factory=list, description="Test assertions")
    dsl_content: Optional[str] = Field(default=None, description="YAML DSL content")
    timeout: int = Field(default=30, description="Timeout in seconds")
    created_at: datetime = Field(default_factory=datetime.now)
    updated_at: datetime = Field(default_factory=datetime.now)

    # Pydantic v2 config
    model_config = {
        "json_encoders": {
            datetime: lambda v: v.isoformat()
        },
        "extra": "allow",
        "arbitrary_types_allowed": True,
    }


class CaseDraft(BaseModel):
    """Draft test case generated from PRD (before user confirmation)."""
    name: str
    source: str
    description: str
    suggested_steps: List[str] = Field(default_factory=list, description="Suggested step descriptions (deprecated, use dsl_content)")
    dsl_content: Optional[str] = Field(default='', description="Complete YAML DSL content")
    confidence: float = Field(default=0.8, ge=0.0, le=1.0)


class CaseCreate(BaseModel):
    """Request model for creating a test case."""
    name: str
    source: Optional[str] = None
    execution_mode: ExecutionMode = ExecutionMode.SCREEN
    dsl_content: Optional[str] = None  # YAML DSL content


class CaseResponse(BaseModel):
    """Response model for a test case."""
    id: str
    name: str
    source: Optional[str]
    execution_mode: ExecutionMode
    step_count: int
    created_at: str
    updated_at: str
