"""
Pydantic models for API request/response validation.
"""

from typing import Any, Dict, List, Optional

from pydantic import BaseModel, Field


class ArgumentMetadata(BaseModel):
    """Metadata for a single argument."""

    name: str
    alias: Optional[str] = None
    long_alias: Optional[str] = None
    type: str = "str"
    required: bool = False
    help: str = ""
    default: Any = ""
    choices: Optional[List[str]] = None
    nargs: Optional[Any] = None


class SnippetMetadata(BaseModel):
    """Metadata for a snippet or pipeline."""

    name: str
    description: str = ""
    arguments: List[ArgumentMetadata] = []
    results: Dict[str, str] = {}
    item_type: str = Field(..., description="'snippet' or 'pipeline'")


class GenerateSingleStepRequest(BaseModel):
    """Request to generate a single-step pipeline YAML."""

    snippet_name: str = Field(..., description="Name of the snippet to use")
    arguments: Dict[str, Any] = Field(..., description="Argument name to value mapping")
    arg_modes: Optional[Dict[str, str]] = Field(
        None, description="Argument modes (Variable/Constant)"
    )
    arg_descriptions: Optional[Dict[str, str]] = Field(
        None, description="Custom descriptions for arguments"
    )
    description: str = Field("Generated pipeline", description="Pipeline description")
    step_id: str = Field("step_1", description="Step ID")
    step_type: str = Field(
        "snippet",
        description="Step type (snippet/batch_snippet/pipeline/batch_pipeline)",
    )
    batch_metadata: Optional[Dict[str, Any]] = Field(
        None, description="Batch metadata for info.batches section"
    )
    argument_forms: Optional[Dict[str, str]] = Field(
        None,
        description="Original argument forms for round-trip preservation (e.g., {i: '-i', input: '--input'})",
    )


class StepConfiguration(BaseModel):
    """Configuration for a single step in a multi-step pipeline."""

    name: str = Field(..., description="Snippet or pipeline name")
    type: str = Field(..., description="'snippet' or 'pipeline'")
    arguments: Dict[str, Any] = Field({}, description="Argument mappings")
    arg_modes: Dict[str, str] = Field({}, description="Argument modes")
    arg_descriptions: Dict[str, str] = Field(
        {}, description="Custom descriptions for arguments"
    )
    depends_on: List[str] = Field([], description="List of step IDs this depends on")
    batch_metadata: Optional[Dict[str, Any]] = Field(
        None, description="Batch metadata for this step"
    )
    argument_forms: Optional[Dict[str, str]] = Field(
        None, description="Original argument forms for round-trip preservation"
    )


class GeneratePipelineRequest(BaseModel):
    """Request to generate a multi-step pipeline YAML."""

    pipeline_name: str = Field(..., description="Pipeline name")
    description: str = Field(..., description="Pipeline description")
    steps: Dict[str, StepConfiguration] = Field(
        ..., description="Step ID to configuration mapping"
    )
    defaults: Optional[Dict[str, Any]] = Field(
        default=None, description="Default values for pipeline arguments"
    )
    choices: Optional[Dict[str, List[str]]] = Field(
        default=None, description="Valid choices for pipeline arguments"
    )


class GenerateYAMLResponse(BaseModel):
    """Response containing generated YAML."""

    yaml: str = Field(..., description="Generated YAML string")


class ValidationError(BaseModel):
    """A single validation error."""

    message: str


class ValidationResponse(BaseModel):
    """Response from pipeline validation."""

    is_valid: bool
    errors: List[str] = []


class ErrorResponse(BaseModel):
    """Error response."""

    detail: str
