from datetime import datetime
from typing import Any

from pydantic import BaseModel, Field, model_validator


class ModelBase(BaseModel):
    code: str
    name: str
    type: str
    tags: list[str] = Field(default_factory=list)
    enabled: bool = True
    dimension: int | None = None
    remote_model_id: str | None = None
    context_length: int | None = None
    max_output_tokens: int | None = None
    supports_stream: bool = True
    supports_tools: bool = False
    priority: int = 100
    extra_config: dict[str, Any] | None = None


class ModelCreate(ModelBase):
    provider_id: int


class ModelUpdate(BaseModel):
    name: str | None = None
    type: str | None = None
    tags: list[str] | None = None
    enabled: bool | None = None
    dimension: int | None = None
    remote_model_id: str | None = None
    context_length: int | None = None
    max_output_tokens: int | None = None
    supports_stream: bool | None = None
    supports_tools: bool | None = None
    priority: int | None = None
    extra_config: dict[str, Any] | None = None


class ModelResponse(ModelBase):
    id: int
    provider_id: int
    provider_name: str | None = None
    is_local: bool = False
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


class ProviderBase(BaseModel):
    name: str
    description: str | None = None
    icon: str | None = None
    color: str | None = None
    default_base_url: str | None = None
    provider_kind: str | None = None
    protocol: str | None = None
    auth_type: str | None = None
    capabilities: list[str] = Field(default_factory=list)
    is_local: bool = False
    healthcheck_path: str | None = None
    extra_config: dict[str, Any] | None = None


class ProviderCreate(ProviderBase):
    configured: bool = False
    api_key: str | None = None
    base_url: str | None = None
    priority: int = 100
    enabled: bool = True


class ProviderUpdate(BaseModel):
    name: str | None = None
    description: str | None = None
    icon: str | None = None
    color: str | None = None
    configured: bool | None = None
    default_base_url: str | None = None
    api_key: str | None = None
    base_url: str | None = None
    priority: int | None = None
    enabled: bool | None = None
    provider_kind: str | None = None
    protocol: str | None = None
    auth_type: str | None = None
    capabilities: list[str] | None = None
    is_local: bool | None = None
    healthcheck_path: str | None = None
    extra_config: dict[str, Any] | None = None


class ProviderConfig(BaseModel):
    model_config = {"populate_by_name": True}
    api_key: str | None = Field(None, alias="apiKey")
    base_url: str | None = Field(None, alias="baseUrl")
    priority: int | None = 100
    enabled: bool | None = True


class ProviderResponse(ProviderBase):
    id: int
    configured: bool
    api_key: str | None = None
    base_url: str | None = None
    priority: int
    enabled: bool
    created_at: datetime
    updated_at: datetime
    models: list[ModelResponse] = Field(default_factory=list)

    @model_validator(mode="after")
    def process_api_key(self):
        from app.core.encryption import encryption_service

        if self.api_key:
            try:
                decrypted_key = encryption_service.decrypt(self.api_key)
                if decrypted_key and len(decrypted_key) > 12:
                    self.api_key = f"{decrypted_key[:8]}...{decrypted_key[-4:]}"
                else:
                    self.api_key = "***"
            except Exception:
                self.api_key = "***"
        if self.auth_type and self.auth_type != "none":
            self.configured = bool(self.api_key or self.base_url)
        else:
            self.configured = bool(self.base_url or self.is_local)
        return self

    class Config:
        from_attributes = True
