"""Pydantic v2 models for BYOK key management.

Defines data structures for encrypted key storage, public key info,
and validation results.
"""

from __future__ import annotations

from datetime import datetime, timezone

from pydantic import BaseModel, ConfigDict, field_validator

SUPPORTED_PROVIDERS: list[str] = [
    "openai",
    "anthropic",
    "openrouter",
    "google",
    "mistral",
    "groq",
    "together",
    "deepseek",
]


def _mask_key(raw_key: str) -> str:
    """Mask an API key for safe display.

    Shows first 3 characters + '...' + last 4 characters.
    Keys shorter than 10 chars get fully masked.
    """
    if len(raw_key) < 10:
        return "***masked***"
    return f"{raw_key[:3]}...{raw_key[-4:]}"


class EncryptedKey(BaseModel):
    """Internal model for a stored, encrypted API key."""

    model_config = ConfigDict(strict=True)

    provider: str
    encrypted_value: str  # base64-encoded Fernet token
    added_at: datetime
    last_used: datetime | None = None
    last_validated: datetime | None = None
    is_valid: bool | None = None  # None = not yet validated

    @field_validator("provider")
    @classmethod
    def _normalize_provider(cls, v: str) -> str:
        return v.strip().lower()


class KeyInfo(BaseModel):
    """Public key info returned by list_providers (no actual key exposed)."""

    model_config = ConfigDict(strict=True)

    provider: str
    masked_key: str  # "sk-...a3Bf"
    added_at: datetime
    last_used: datetime | None = None
    is_valid: bool | None = None


class KeyValidation(BaseModel):
    """Result of an API key validation attempt."""

    model_config = ConfigDict(strict=True)

    provider: str
    is_valid: bool
    error: str | None = None
    models_available: int | None = None  # how many models the key can access
    validated_at: datetime

    @classmethod
    def success(cls, provider: str, *, models_available: int | None = None) -> KeyValidation:
        """Factory for a successful validation."""
        return cls(
            provider=provider,
            is_valid=True,
            models_available=models_available,
            validated_at=datetime.now(timezone.utc),
        )

    @classmethod
    def failure(cls, provider: str, error: str) -> KeyValidation:
        """Factory for a failed validation."""
        return cls(
            provider=provider,
            is_valid=False,
            error=error,
            validated_at=datetime.now(timezone.utc),
        )
