"""AI domain — request/response schemas."""
from __future__ import annotations

from datetime import datetime
from typing import Any, Optional
from uuid import UUID

from pydantic import BaseModel, field_validator

_VALID_EMBEDDING_PROVIDERS = ("cf_workers_ai", "openai", "byok")
_VALID_METRICS = ("cosine", "euclidean", "dot-product")


class AIConfigResponse(BaseModel):
    project_id: UUID
    embedding_provider: str
    embedding_model: Optional[str] = None
    # Whether BYOK embedding key is configured (never the key value)
    embedding_byok_configured: bool = False
    completion_providers: list[str] = []
    # Which BYOK completion providers have keys configured
    completion_byok_providers: list[str] = []
    updated_at: Optional[datetime] = None

    model_config = {"from_attributes": True}


class UpdateAIConfigRequest(BaseModel):
    embedding_provider: Optional[str] = None
    # BYOK API key for embeddings — stored encrypted, never returned
    embedding_byok_key: Optional[str] = None

    @field_validator("embedding_provider")
    @classmethod
    def validate_embedding_provider(cls, v: Optional[str]) -> Optional[str]:
        if v is not None and v not in _VALID_EMBEDDING_PROVIDERS:
            raise ValueError(f"embedding_provider must be one of: {', '.join(_VALID_EMBEDDING_PROVIDERS)}")
        return v


class SetBYOKCompletionKeyRequest(BaseModel):
    """Store a BYOK completion API key for a provider (openai or anthropic)."""

    provider: str
    api_key: str

    @field_validator("provider")
    @classmethod
    def validate_provider(cls, v: str) -> str:
        if v not in ("openai", "anthropic"):
            raise ValueError("provider must be 'openai' or 'anthropic'")
        return v


class EmbedConfigResponse(BaseModel):
    id: UUID
    project_id: UUID
    entity_key: str
    field_key: str
    auto_embed: bool
    model_override: Optional[str] = None
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


class CreateEmbedConfigRequest(BaseModel):
    entity_key: str
    field_key: str
    auto_embed: bool = True
    model_override: Optional[str] = None

    @field_validator("entity_key", "field_key")
    @classmethod
    def validate_slug(cls, v: str) -> str:
        v = v.strip()
        if not v:
            raise ValueError("Must not be empty")
        return v


class UpdateEmbedConfigRequest(BaseModel):
    auto_embed: Optional[bool] = None
    model_override: Optional[str] = None


class VectorizeConfigResponse(BaseModel):
    workspace_id: UUID
    vectorize_index_id: str
    index_name: str
    dimensions: int
    metric: str
    needs_reembed: bool
    created_at: datetime

    model_config = {"from_attributes": True}


class ProvisionVectorizeRequest(BaseModel):
    dimensions: int = 768
    metric: str = "cosine"

    @field_validator("dimensions")
    @classmethod
    def validate_dimensions(cls, v: int) -> int:
        if v not in (768, 1536, 3072):
            raise ValueError("dimensions must be 768, 1536, or 3072")
        return v

    @field_validator("metric")
    @classmethod
    def validate_metric(cls, v: str) -> str:
        if v not in _VALID_METRICS:
            raise ValueError(f"metric must be one of: {', '.join(_VALID_METRICS)}")
        return v


class ReembedTriggerResponse(BaseModel):
    queued: bool
    message: str
