# Auto-generated by DjangoCFG - see CLAUDE.md

from __future__ import annotations
import datetime
from typing import Any

from pydantic import BaseModel, ConfigDict, Field

from ..enums import (
    CategorySlug,
    LLMModelDetailSyncSource,
    PresetSlug,
    PresetSortBy,
)


class LLMModelList(BaseModel):
    """
    Lightweight serializer for model listing.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    model_id: str = Field(description="Model identifier (e.g., 'openai/...", max_length=100)
    name: str = Field(description='Human-readable model name', max_length=200)
    owned_by: str = Field(description="Provider/owner name (e.g., 'Open...", max_length=100)
    context_length: int = Field(
    description='Maximum context length in tokens',
    ge=-2147483648,
    le=2147483647,
)
    supports_vision: bool | None = Field(None, description='Whether model supports image inputs')
    supports_tools: bool | None = Field(None, description='Whether model supports tool/func...')
    pricing: dict[str, Any] = Field(description='Get simplified pricing info.')



class PaginatedLLMModelListList(BaseModel):
    """
    
    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    count: int = Field(description='Total number of items across all...')
    page: int = Field(description='Current page number (1-based)')
    pages: int = Field(description='Total number of pages')
    page_size: int = Field(description='Number of items per page')
    has_next: bool = Field(description='Whether there is a next page')
    has_previous: bool = Field(description='Whether there is a previous page')
    next_page: int | None = Field(None, description='Next page number (null if no nex...')
    previous_page: int | None = Field(None, description='Previous page number (null if no...')
    results: list[LLMModelList] = Field(description='Array of items for current page')



class LLMModelPricing(BaseModel):
    """
    Pricing information serializer.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    prompt: Any = Field(
    description='Price per million prompt tokens ...',
    pattern='^-?\\d{0,4}(?:\\.\\d{0,6})?$',
)
    completion: Any = Field(
    description='Price per million completion tok...',
    pattern='^-?\\d{0,4}(?:\\.\\d{0,6})?$',
)
    image: Any | None = Field(
    None,
    description='Price per image (USD)',
    pattern='^-?\\d{0,4}(?:\\.\\d{0,6})?$',
)



class LLMModelDetail(BaseModel):
    """
    Detailed serializer for single model.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    id: str = ...
    model_id: str = Field(description="Model identifier (e.g., 'openai/...", max_length=100)
    name: str = Field(description='Human-readable model name', max_length=200)
    owned_by: str = Field(description="Provider/owner name (e.g., 'Open...", max_length=100)
    provider: Any = ...
    sync_source: LLMModelDetailSyncSource = Field(
    description='Sync pipeline that manages this ...',
)
    description: str | None = Field(None, description='Model description')
    context_length: int = Field(
    description='Maximum context length in tokens',
    ge=-2147483648,
    le=2147483647,
)
    max_output_tokens: int | None = Field(
    None,
    description='Maximum output tokens (if limited)',
    ge=-2147483648,
    le=2147483647,
)
    supports_vision: bool | None = Field(None, description='Whether model supports image inputs')
    supports_tools: bool | None = Field(None, description='Whether model supports tool/func...')
    supports_streaming: bool | None = Field(
    None,
    description='Whether model supports streaming...',
)
    supports_json_mode: bool | None = Field(
    None,
    description='Whether model supports JSON outp...',
)
    pricing: LLMModelPricing = ...
    architecture: dict[str, Any] | None = Field(
    None,
    description='Architecture details (modality, ...',
)
    top_provider: dict[str, Any] | None = Field(
    None,
    description='Top provider information from Op...',
)
    is_active: bool | None = Field(None, description='Whether the model is available f...')
    last_synced_at: datetime.datetime = Field(description='Last time this model was synced')
    created_at: datetime.datetime = ...
    updated_at: datetime.datetime = ...



class CostCalculationRequestRequest(BaseModel):
    """
    Request serializer for cost calculation.

    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    input_tokens: int = Field(description='Number of input tokens', ge=0)
    output_tokens: int = Field(description='Number of output tokens', ge=0)



class CostCalculationResponse(BaseModel):
    """
    Response serializer for cost calculation.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    model_id: str = Field(description='Model ID')
    input_cost_usd: float = Field(description='Cost of input tokens in USD')
    output_cost_usd: float = Field(description='Cost of output tokens in USD')
    total_cost_usd: float = Field(description='Total cost in USD')
    input_tokens: int = Field(description='Number of input tokens')
    output_tokens: int = Field(description='Number of output tokens')



class CapabilitiesListResponse(BaseModel):
    """
    Response serializer for capabilities list.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    capabilities: list[str] = Field(description='List of valid capabilities')



class Category(BaseModel):
    """
    Serializer for model category.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    slug: CategorySlug = Field(description="Category slug (e.g., 'code', 'vi...")
    name: str = Field(description='Category name')
    description: str = Field(description='Category description')
    icon: str = Field(description='Icon identifier')
    is_active: bool = Field(description='Whether category is active')



class CategoriesListResponse(BaseModel):
    """
    Response serializer for categories list.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    categories: list[Category] = Field(description='List of categories')



class Preset(BaseModel):
    """
    Serializer for model preset.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    slug: PresetSlug = Field(description="Preset slug (e.g., 'cheap', 'sma...")
    name: str = Field(description='Preset name')
    description: str = Field(description='Preset description')
    sort_by: PresetSortBy = Field(description='Primary sort field  * `price` - ...')
    sort_ascending: bool = Field(description='Sort direction')
    min_quality_score: int | None = Field(None, description='Minimum quality score filter')
    max_quality_score: int | None = Field(None, description='Maximum quality score filter')
    max_price_per_1m: Any | None = Field(
    None,
    description='Maximum price per 1M tokens',
    pattern='^-?\\d{0,4}(?:\\.\\d{0,6})?$',
)
    is_active: bool = Field(description='Whether preset is active')



class PresetsListResponse(BaseModel):
    """
    Response serializer for presets list.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    presets: list[Preset] = Field(description='List of presets')



class ProviderInfo(BaseModel):
    """
    Provider info serializer.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    name: str = Field(description='Provider name')
    model_count: int = Field(description='Number of models')



class ProvidersResponse(BaseModel):
    """
    Response serializer for providers list.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    providers: list[ProviderInfo] = Field(description='List of providers')



class ResolveRequestRequest(BaseModel):
    """
    Request serializer for model resolution.

    Request model (no read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    alias: str = Field(description="Model alias (e.g., '@cheap', '@s...", min_length=1)
    max_price_per_1m: Any | None = Field(
    None,
    description='Maximum price per 1M tokens (USD)',
    pattern='^-?\\d{0,4}(?:\\.\\d{0,6})?$',
)
    min_quality_score: int | None = Field(
    None,
    description='Minimum quality score (1-100)',
    ge=1,
    le=100,
)
    excluded_providers: list[str] | None = Field(None, description='Providers to exclude')
    required_context_length: int | None = Field(
    None,
    description='Minimum context length in tokens',
    ge=1000,
)



class AlternativeModel(BaseModel):
    """
    Serializer for alternative model suggestion.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    model_id: str = Field(description='Model identifier')
    model_name: str = Field(description='Human-readable model name')
    reason: str = Field(description='Why this alternative was not sel...')



class ResolveCriteria(BaseModel):
    """
    Serializer for criteria used in resolution.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    tier: str = Field(description='Base tier used')
    capabilities: list[str] = Field(description='Required capabilities')
    categories: list[str] = Field(description='Required categories')
    sort_by: str = Field(description='Sort field used')
    sort_order: str = Field(description='Sort direction (asc/desc)')



class ResolveResponse(BaseModel):
    """
    Response serializer for model resolution.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    model_id: str = Field(description='Resolved model identifier')
    model_name: str = Field(description='Human-readable model name')
    requested_alias: str = Field(description='Original alias requested')
    match_score: float = Field(description='Match confidence (0-1)')
    selection_reason: str = Field(description='Why this model was selected')
    alternatives: list[AlternativeModel] = Field(description='Alternative models considered')
    criteria: ResolveCriteria = ...
    resolution_ms: float = Field(description='Resolution time in milliseconds')



class StatsResponse(BaseModel):
    """
    Response serializer for model statistics.

    Response model (includes read-only fields).
    """

    model_config = ConfigDict(
        validate_assignment=True,
        extra="allow",
        frozen=False,
    )

    total_models: int = Field(description='Total number of models')
    active_models: int = Field(description='Number of active models')
    vision_models: int = Field(description='Number of vision-capable models')
    tool_models: int = Field(description='Number of tool-capable models')
    provider_count: int = Field(description='Number of providers')



