"""
API request and response models.

Defines Pydantic models for API input validation and response formatting.
Uses shared input models from core module.
"""

from typing import Any, Optional
from uuid import uuid4

from pydantic import BaseModel, Field

# Import shared models from core
from ..core.input_models import ContentItem, RequestMetadata

# Re-export for convenience
__all__ = [
    "ContentItem",
    "RequestMetadata",
    "EvaluationRequest",
    "EvaluationResponse",
    "FailedItem",
    "HealthResponse",
    "CurriculumVersion",
    "CurriculumInfo",
    "CurriculumsResponse",
    "VersionsResponse",
    "ErrorResponse",
]


class EvaluationRequest(BaseModel):
    """
    Request model for content evaluation endpoint.
    
    Uses a single array-based format. Each item in the array is evaluated
    independently and in parallel.
    """

    generated_content: list[ContentItem] = Field(
        ...,
        description="Array of content items to evaluate (1-100 items)",
        min_length=1,
        max_length=100
    )
    curriculum_version: Optional[str] = Field(
        default=None,
        description="Curriculum version to use (e.g., '1.2'). If not specified, uses the latest version."
    )
    
    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "generated_content": [
                        {
                            "content": "What is the capital of France?"
                        }
                    ]
                },
                {
                    "generated_content": [
                        {
                            "id": "q1",
                            "curriculum": "common_core",
                            "request": {
                                "grade": "7",
                                "subject": "mathematics",
                                "type": "mcq",
                                "difficulty": "medium",
                                "locale": "en-US",
                                "skills": {
                                    "lesson_title": "Congruent and Similar Triangles",
                                    "substandard_id": "CCSS.MATH.CONTENT.7.G.A.1+3"
                                },
                                "instruction": "A real-world problem involving congruent and similar triangles"
                            },
                            "content": {
                                "question": "Triangle ABC is similar to triangle DEF. If AB = 6 cm, BC = 8 cm, and DE = 9 cm, what is the length of EF?",
                                "answer": "B",
                                "answer_explanation": "Since the triangles are similar, corresponding sides are proportional. AB/DE = BC/EF, so 6/9 = 8/EF, which gives EF = 12 cm",
                                "answer_options": [
                                    {"key": "A", "text": "10 cm"},
                                    {"key": "B", "text": "12 cm"},
                                    {"key": "C", "text": "14 cm"},
                                    {"key": "D", "text": "16 cm"}
                                ]
                            }
                        }
                    ],
                    "curriculum_version": "1.2"
                },
                {
                    "generated_content": [
                        {
                            "content": "Solve: 2x + 5 = 15",
                            "request": {"grade": "6", "subject": "math"}
                            },
                        {
                            "content": "What is photosynthesis?",
                            "curriculum": "ngss"
                        }
                    ]
                }
            ]
        }
    }


# Response Models

class FailedItem(BaseModel):
    """Information about a failed evaluation item."""
    
    item_id: str = Field(..., description="ID of the failed item")
    error: str = Field(..., description="Error message")


class EvaluationResponse(BaseModel):
    """
    Response model for evaluation endpoints.

    The evaluations dict contains pass-through results from the evaluation
    service. No schema is enforced on individual evaluation results.
    """
    
    request_id: str = Field(
        default_factory=lambda: str(uuid4()),
        description="Unique request identifier"
    )
    evaluations: dict[str, Any] = Field(
        ...,
        description="Evaluations keyed by item ID (pass-through from service)"
    )
    evaluation_time_seconds: float = Field(
        ...,
        description="Total evaluation time in seconds"
    )
    inceptbench_version: str = Field(
        ...,
        description="InceptBench version used for evaluation"
    )
    curriculum_version: Optional[str] = Field(
        default=None,
        description="Curriculum version used for evaluation (null if using latest)"
    )
    failed_items: Optional[list[FailedItem]] = Field(
        default=None,
        description="Items that failed evaluation (null if all succeeded)"
    )
    
    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "request_id": "550e8400-e29b-41d4-a716-446655440000",
                    "evaluations": {
                        "q1": {
                                "content_type": "question",
                                "overall": {
                                    "score": 0.9,
                                "reasoning": "Strong question.",
                                "suggested_improvements": None
                                },
                                "factual_accuracy": {
                                    "score": 1.0,
                                "reasoning": "Accurate.",
                                    "suggested_improvements": None
                                },
                                "weighted_score": 0.8387
                        }
                    },
                    "evaluation_time_seconds": 12.34,
                    "inceptbench_version": "x.y.z",
                    "curriculum_version": "1.2",
                    "failed_items": None
                }
            ]
        }
    }


class HealthResponse(BaseModel):
    """Response model for health check endpoint."""
    
    status: str = Field(..., description="Service health status")
    version: str = Field(..., description="API version")
    service: str = Field(..., description="Service name")


class CurriculumVersion(BaseModel):
    """Single curriculum version info."""
    
    version: str = Field(..., description="Version string (e.g., '1.2')")
    version_date: str = Field(..., description="Version release date (e.g., '2026-01-14')")


class CurriculumInfo(BaseModel):
    """Detailed information about a curriculum."""
    
    versions: list[CurriculumVersion] = Field(..., description="Available versions")
    latest: str = Field(..., description="Latest version string")
    description: str = Field(..., description="Curriculum description")


class CurriculumsResponse(BaseModel):
    """Response model for curriculum listing endpoint."""
    
    default_curriculum: str = Field(..., description="Default curriculum name")
    curricula: dict[str, CurriculumInfo] = Field(..., description="Curricula with version info")


class VersionsResponse(BaseModel):
    """Response model for InceptBench versions endpoint."""
    
    current: str = Field(..., description="Current/latest InceptBench version")
    supported_versions: list[str] = Field(
        ..., 
        description="List of all supported InceptBench versions (can be used with version query param)"
    )
    default: str = Field(..., description="Default version used when none specified")


class ErrorResponse(BaseModel):
    """Response model for error responses."""

    error: str = Field(..., description="Error type")
    message: str = Field(..., description="Error message")
    detail: Optional[str] = Field(None, description="Additional error details")
