"""
DSL Template Models
Templates for reusable test case patterns
"""

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

from pydantic import BaseModel, Field


class TemplateCategory(str, Enum):
    """Template categories."""
    CLI = "cli"
    API = "api"
    TUI = "tui"
    GUI = "gui"
    AUTH = "auth"
    DATABASE = "database"
    WORKFLOW = "workflow"
    OTHER = "other"


class TemplateVariable(BaseModel):
    """Variable definition for template."""
    name: str = Field(..., description="Variable name")
    description: str = Field(default="", description="Variable description")
    default_value: Optional[str] = Field(default=None, description="Default value")
    required: bool = Field(default=True, description="Whether variable is required")


class TemplateMetadata(BaseModel):
    """Template metadata."""
    author: str = Field(default="", description="Template author")
    version: str = Field(default="1.0", description="Template version")
    tags: List[str] = Field(default_factory=list, description="Template tags")
    category: TemplateCategory = Field(default=TemplateCategory.OTHER, description="Template category")


class DSLTemplate(BaseModel):
    """DSL Template for reusable test patterns."""
    id: str = Field(..., description="Template unique ID")
    name: str = Field(..., description="Template name")
    description: str = Field(default="", description="Template description")
    target_type: str = Field(default="cli", description="Target type: cli, api, tui, gui")

    # Template content
    dsl_template: str = Field(..., description="DSL YAML template with placeholders")
    variables: List[TemplateVariable] = Field(default_factory=list, description="Template variables")

    # Metadata
    metadata: TemplateMetadata = Field(default_factory=TemplateMetadata, description="Template metadata")

    # Timestamps
    created_at: str = Field(default_factory=lambda: datetime.now().isoformat())
    updated_at: str = Field(default_factory=lambda: datetime.now().isoformat())

    # Usage stats
    usage_count: int = Field(default=0, description="Number of times used")

    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }


class TemplateCreate(BaseModel):
    """Request model for creating a template."""
    name: str = Field(..., description="Template name")
    description: str = Field(default="", description="Template description")
    target_type: str = Field(default="cli", description="Target type")
    dsl_template: str = Field(..., description="DSL YAML template")
    variables: List[TemplateVariable] = Field(default_factory=list)
    metadata: Optional[TemplateMetadata] = None


class TemplateUpdate(BaseModel):
    """Request model for updating a template."""
    name: Optional[str] = None
    description: Optional[str] = None
    dsl_template: Optional[str] = None
    variables: Optional[List[TemplateVariable]] = None
    metadata: Optional[TemplateMetadata] = None


class TemplateResponse(BaseModel):
    """Response model for template."""
    id: str
    name: str
    description: str
    target_type: str
    variables: List[TemplateVariable]
    metadata: TemplateMetadata
    created_at: str
    updated_at: str
    usage_count: int


class TemplateInstantiation(BaseModel):
    """Request to instantiate a template into a test case."""
    template_id: str = Field(..., description="Template ID")
    project_id: str = Field(..., description="Target project ID")
    case_name: str = Field(..., description="Name for the new test case")
    variables: Dict[str, Any] = Field(default_factory=dict, description="Variable values")
