"""Pydantic models for the service registry API."""

from __future__ import annotations

from typing import Any

from pydantic import BaseModel, Field, field_validator


def _validate_config_keys(config: dict[str, Any]) -> dict[str, Any]:
    """Reject credential keys in non-secret service config.

    Secrets are sent in the separate ``secrets`` mapping; the plain ``config``
    object must never hold them.
    """
    forbidden = {
        "password",
        "token",
        "secret",
        "api_key",
        "apikey",
        "private_key",
        "passphrase",
        "credential",
    }

    def _check(value: Any) -> None:
        if isinstance(value, dict):
            for key, child in value.items():
                if key.lower() in forbidden:
                    raise ValueError(f"Credential key '{key}' is not allowed in service config")
                _check(child)
        elif isinstance(value, list):
            for item in value:
                _check(item)

    _check(config)
    return config


class ServiceInstanceInput(BaseModel):
    """Payload for creating or updating a service instance."""

    id: str | None = None
    service_type: str = Field(..., min_length=1)
    name: str = Field(..., min_length=1)
    config: dict[str, Any] = Field(default_factory=dict)
    secrets: dict[str, str] = Field(default_factory=dict)
    enabled: bool = True

    @field_validator("config")
    @classmethod
    def reject_credential_keys(cls, value: dict[str, Any]) -> dict[str, Any]:
        return _validate_config_keys(value or {})


class ServiceInstance(BaseModel):
    """Persisted service instance returned by the API (no plaintext secrets)."""

    id: str
    service_type: str
    name: str
    config: dict[str, Any]
    secrets_set: dict[str, bool]
    enabled: bool
    created_at: int
    updated_at: int


class SecretFieldInfo(BaseModel):
    key: str
    label: str
    required: bool = False
    helper: str | None = None


class WidgetKindInfo(BaseModel):
    kind: str
    name: str
    description: str
    config_schema: dict[str, Any]
    default_config: dict[str, Any]
    refresh_interval_ms: int


class ServiceTypeInfo(BaseModel):
    """Metadata about a registered service type."""

    service_type: str
    name: str
    description: str
    config_schema: dict[str, Any]
    secret_fields: list[SecretFieldInfo]
    widget_kinds: list[WidgetKindInfo]
