"""Data models for registry responses.

This module defines dataclasses for model and deployment configurations
retrieved from the Model Registry API.
"""

from dataclasses import dataclass, field
from typing import Dict, Optional, Any

# Valid model types (subtypes for the two-field taxonomy)
# These are used with model_category to determine metric routing
VALID_MODEL_TYPES = [
    "regression",
    "time-series",
    "classification",
    "generative",
    "agentic",
]

# Valid model categories (high-level categorization)
VALID_MODEL_CATEGORIES = [
    "internal",
    "vendor",
]

# Legacy model_type values (deprecated, will be auto-migrated)
LEGACY_MODEL_TYPES = ["internal", "generative", "vendor"]


@dataclass
class ModelConfig:
    """Model configuration from registry.

    Contains model metadata, thresholds, and additional resource attributes
    retrieved from the registry. Uses two-field taxonomy for model classification.

    Attributes:
        service_name: Name of the service/application
        model_id: Unique model identifier
        model_version: Model version string (from top-level API response)
        team_name: Team responsible for the model
        model_category: High-level category ("internal" or "vendor")
        model_type: Specific type ("regression", "time-series", "classification", "generative", "agentic")
        registry_id: Optional registry identifier (can be null for vendor models)
        deployment_id: Optional deployment identifier (can be null for vendor models)
        thresholds: Alert thresholds for metrics (e.g., {"MAE": 12.5, "RMSE": 18.3})
        phi_fields: PHI field definitions (can be empty dict or nested with criticality)
        extra_resource: Additional OpenTelemetry resource attributes (nested in config JSONB)
        association_id_column: Optional column name for time-series association IDs
        created_at: Optional timestamp when model was created
        updated_at: Optional timestamp when model was last updated

    Example:
        >>> config = ModelConfig(
        ...     service_name="readmission-model",
        ...     model_id="mdl-001",
        ...     model_version="2.0.0",
        ...     team_name="clinical-ai",
        ...     model_category="internal",
        ...     model_type="regression",
        ...     registry_id="readmission-v2",
        ...     deployment_id="gke-prod-001",
        ...     thresholds={"accuracy": 0.85, "latency_ms": 500},
        ...     phi_fields={"patient_id": {"criticality": "yes"}},
        ...     extra_resource={"deployment.env": "production"}
        ... )
    """

    # Core fields (required)
    service_name: str
    model_id: str
    model_version: str
    team_name: str
    model_category: str
    model_type: str

    # Optional identifiers (can be null for vendor models)
    registry_id: Optional[str] = None
    deployment_id: Optional[str] = None

    # Thresholds (top-level in API response, model-type specific)
    thresholds: Dict[str, float] = field(default_factory=dict)

    # PHI fields (can be empty dict or nested structure with criticality)
    phi_fields: Dict[str, Any] = field(default_factory=dict)

    # Extra resource attributes (nested in config JSONB in API response)
    extra_resource: Dict[str, str] = field(default_factory=dict)

    # Time-series specific field (optional)
    association_id_column: Optional[str] = None

    # Timestamps (optional, for debugging)
    created_at: Optional[str] = None
    updated_at: Optional[str] = None

    def __post_init__(self) -> None:
        """Validate model configuration after initialization."""
        # Validate model_category
        if self.model_category not in VALID_MODEL_CATEGORIES:
            raise ValueError(
                f"model_category must be one of {VALID_MODEL_CATEGORIES}, got '{self.model_category}'"
            )

        # Validate model_type
        if self.model_type not in VALID_MODEL_TYPES:
            # Check if it's a legacy value that needs migration
            if self.model_type in LEGACY_MODEL_TYPES:
                raise ValueError(
                    f"model_type '{self.model_type}' is a legacy value. "
                    f"Registry should provide both model_category and model_type fields. "
                    f"Valid model_type values: {VALID_MODEL_TYPES}"
                )
            raise ValueError(
                f"model_type must be one of {VALID_MODEL_TYPES}, got '{self.model_type}'"
            )


@dataclass
class DeploymentConfig:
    """Deployment-specific configuration from registry.

    Contains deployment metadata and resource attribute overrides
    for runtime-specific configuration.

    Attributes:
        deployment_id: Unique deployment identifier
        environment: Deployment environment (e.g., "production", "staging")
        region: Geographic region or datacenter
        resource_overrides: Resource attributes specific to this deployment

    Example:
        >>> config = DeploymentConfig(
        ...     deployment_id="dep-prod-001",
        ...     environment="production",
        ...     region="us-east-1",
        ...     resource_overrides={"deployment.zone": "az-1"}
        ... )
    """

    deployment_id: str
    environment: str
    region: str
    resource_overrides: Dict[str, str] = field(default_factory=dict)
