"""Pydantic schemas for enricher templates."""

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

from pydantic import UUID4, BaseModel, Field, field_validator

from .base import ORMBase


class EnricherTemplateCreate(BaseModel):
    """Schema for creating a new enricher template."""

    name: str = Field(
        ..., min_length=1, max_length=255, description="Name of the template"
    )
    description: Optional[str] = Field(
        None, max_length=1000, description="Description of the template"
    )
    category: str = Field(
        ..., min_length=1, max_length=100, description="Category (e.g., Ip, Domain)"
    )
    version: float = Field(default=1.0, ge=0, description="Template version")
    content: Dict[str, Any] = Field(
        ..., description="Template content as parsed YAML/JSON"
    )
    is_public: bool = Field(
        default=False, description="Whether the template is publicly visible"
    )

    @field_validator("content")
    @classmethod
    def validate_content(cls, v: Dict[str, Any]) -> Dict[str, Any]:
        """Validate that content has required template fields."""
        required_fields = [
            "name",
            "category",
            "version",
            "input",
            "request",
            "output",
            "response",
        ]
        missing = [f for f in required_fields if f not in v]
        if missing:
            raise ValueError(
                f"Missing required fields in content: {', '.join(missing)}"
            )

        # Validate input
        if "input" in v and "type" not in v.get("input", {}):
            raise ValueError("input.type is required")

        # Validate request
        request = v.get("request", {})
        if "method" not in request:
            raise ValueError("request.method is required")
        if request.get("method") not in ["GET", "POST"]:
            raise ValueError("request.method must be GET or POST")
        if "url" not in request:
            raise ValueError("request.url is required")

        # Validate output
        if "output" in v and "type" not in v.get("output", {}):
            raise ValueError("output.type is required")

        # Validate response
        response = v.get("response", {})
        if "expect" not in response:
            raise ValueError("response.expect is required")
        if response.get("expect") not in ["json", "xml", "text"]:
            raise ValueError("response.expect must be json, xml, or text")

        return v


class EnricherTemplateUpdate(BaseModel):
    """Schema for updating an existing enricher template."""

    name: Optional[str] = Field(None, min_length=1, max_length=255)
    description: Optional[str] = Field(None, max_length=1000)
    category: Optional[str] = Field(None, min_length=1, max_length=100)
    version: Optional[float] = Field(None, ge=0)
    content: Optional[Dict[str, Any]] = None
    is_public: Optional[bool] = None

    @field_validator("content")
    @classmethod
    def validate_content(cls, v: Optional[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
        """Validate content if provided."""
        if v is None:
            return v

        required_fields = [
            "name",
            "category",
            "version",
            "input",
            "request",
            "output",
            "response",
        ]
        missing = [f for f in required_fields if f not in v]
        if missing:
            raise ValueError(
                f"Missing required fields in content: {', '.join(missing)}"
            )

        return v


class EnricherTemplateRead(ORMBase):
    """Schema for reading an enricher template."""

    id: UUID4
    name: str
    description: Optional[str]
    category: str
    version: float
    content: Dict[str, Any]
    is_public: bool
    owner_id: UUID4
    created_at: datetime
    updated_at: datetime


class EnricherTemplateList(ORMBase):
    """Schema for listing enricher templates (minimal fields)."""

    id: UUID4
    name: str
    description: Optional[str]
    category: str
    version: float
    is_public: bool
    owner_id: UUID4
    created_at: datetime
    updated_at: datetime


class EnricherTemplateTestRequest(BaseModel):
    """Schema for testing an enricher template by ID."""

    input_value: str = Field(
        ..., min_length=1, description="The value to test the template with"
    )


class EnricherTemplateTestContentRequest(BaseModel):
    """Schema for testing template content directly (without saving)."""

    input_value: str = Field(
        ..., min_length=1, description="The value to test the template with"
    )
    content: Dict[str, Any] = Field(..., description="Template content to test")


class EnricherTemplateTestResponse(BaseModel):
    """Schema for test response."""

    success: bool
    data: Optional[Dict[str, Any]] = None
    error: Optional[str] = None
    status_code: Optional[int] = None
    url: str


class EnricherTemplateGenerateRequest(BaseModel):
    """Schema for AI-assisted template generation."""

    prompt: str = Field(
        ...,
        min_length=10,
        max_length=16000,
        description="Free-text description of the desired enricher template",
    )
    input_type: Optional[str] = Field(
        None, description="Flowsint input type name (e.g. 'Ip', 'Domain')"
    )
    output_type: Optional[str] = Field(
        None, description="Flowsint output type name (e.g. 'Ip', 'SocialAccount')"
    )


class EnricherTemplateGenerateResponse(BaseModel):
    """Schema for the generated template response."""

    yaml_content: str = Field(
        ..., description="Raw YAML string of the generated template"
    )
