"""Request and response schemas for the model configuration center."""

from datetime import datetime

from pydantic import BaseModel, Field

from agenteval.models import ModelCapability, ModelModality, ModelProtocol
from agenteval.storage.db import ModelConfigDB, iso_utc


class ModelConfigCreate(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    provider: ModelProtocol = ModelProtocol.OPENAI_COMPATIBLE
    capability: ModelCapability
    endpoint_url: str
    model_name: str | None = None
    vendor_name: str = ""
    input_modalities: list[ModelModality] = Field(default_factory=lambda: [ModelModality.TEXT], min_length=1)
    output_modalities: list[ModelModality] = Field(default_factory=lambda: [ModelModality.TEXT], min_length=1)
    context_window: int | None = Field(default=None, gt=0)
    max_output_tokens: int | None = Field(default=None, gt=0)
    supports_streaming: bool = False
    supports_tool_calling: bool = False
    supports_structured_output: bool = False
    supports_reasoning: bool = False
    region: str = ""
    documentation_url: str | None = None
    api_key: str | None = None
    enabled: bool = True
    is_default: bool = False
    is_analysis_default: bool = False
    description: str = ""


class ModelConfigUpdate(ModelConfigCreate):
    clear_api_key: bool = False


class ModelConfigResponse(BaseModel):
    id: str
    name: str
    provider: ModelProtocol
    capability: ModelCapability
    endpoint_url: str
    model_name: str | None
    vendor_name: str
    input_modalities: list[ModelModality]
    output_modalities: list[ModelModality]
    context_window: int | None
    max_output_tokens: int | None
    supports_streaming: bool
    supports_tool_calling: bool
    supports_structured_output: bool
    supports_reasoning: bool
    region: str
    documentation_url: str | None
    has_api_key: bool
    enabled: bool
    is_default: bool
    is_analysis_default: bool
    description: str
    created_at: str | None
    updated_at: str | None

    @classmethod
    def from_db(cls, config: ModelConfigDB) -> "ModelConfigResponse":
        return cls(
            id=config.id or "",
            name=config.name,
            provider=ModelProtocol(config.provider),
            capability=ModelCapability(config.capability),
            endpoint_url=config.endpoint_url,
            model_name=config.model_name,
            vendor_name=config.vendor_name,
            input_modalities=[ModelModality(item) for item in config.get_input_modalities()],
            output_modalities=[ModelModality(item) for item in config.get_output_modalities()],
            context_window=config.context_window,
            max_output_tokens=config.max_output_tokens,
            supports_streaming=config.supports_streaming,
            supports_tool_calling=config.supports_tool_calling,
            supports_structured_output=config.supports_structured_output,
            supports_reasoning=config.supports_reasoning,
            region=config.region,
            documentation_url=config.documentation_url,
            has_api_key=bool(config.api_key_encrypted),
            enabled=config.enabled,
            is_default=config.is_default,
            is_analysis_default=config.is_analysis_default,
            description=config.description,
            created_at=iso_utc(config.created_at),
            updated_at=iso_utc(config.updated_at),
        )


class ModelConfigReference(BaseModel):
    scenario_id: str
    scenario_name: str
    purpose: str


class ModelConnectionTestResponse(BaseModel):
    ok: bool
    message: str
    tested_at: datetime
