from datetime import datetime
from typing import Any
from uuid import UUID

from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator


class OrganizationDetails(BaseModel):
    """
    Simplified Pydantic model for organization details with basic type validation.
    """

    model_config = ConfigDict(
        extra="allow",  # Allows additional fields without validation
        str_strip_whitespace=True,
        str_min_length=1,
        frozen=True,  # Make instances immutable
    )

    # UUID field
    organization_id: UUID = Field(..., description="Organization UUID (must be version 4)")

    # String fields
    organization_name: str
    PK: str
    SK: str
    source: str

    # DateTime fields
    created: datetime
    last_updated: datetime
    last_seen: datetime

    # Numeric fields
    ttl: float
    connection_count: int = Field(ge=0)

    # List fields
    connections: list[Any] = Field(default_factory=list)
    connection_types: list[Any] = Field(default_factory=list)

    # Boolean fields
    is_enabled: bool = Field(default=True)
    metrics_enabled: bool = Field(default=False)
    billing_enabled: bool = Field(default=True)
    resources_enabled: bool = Field(default=False)


@field_validator("organization_id")
def validate_uuid_version(_cls, v: UUID) -> UUID:
    """Ensure UUID is version 4"""
    if v.version != 4:
        raise ValueError("organization_id must be a version 4 UUID")
    return v


class Organizations(dict[UUID, OrganizationDetails]):
    """
    Custom dictionary class that ensures keys are UUIDv4 and values are OrganizationDetails.
    """

    @model_validator(mode="before")
    def validate_uuid_keys(self, values):
        """Validate all dictionary keys are UUIDv4"""
        if not isinstance(values, dict):
            raise ValueError("Organizations must be a dictionary")

        validated = {}
        for key, value in values.items():
            # Convert string UUID to UUID object if necessary
            if isinstance(key, str):
                try:
                    key = UUID(key)
                except ValueError as e:
                    raise ValueError(f"Invalid UUID key: {key}") from e

            # Validate UUID version
            if key.version != 4:
                raise ValueError(f"UUID key must be version 4: {key}")

            # Ensure organization_id matches the key
            if isinstance(value, dict):
                value["organization_id"] = str(key)
            elif isinstance(value, OrganizationDetails):
                if value.organization_id != key:
                    raise ValueError(f"Organization ID mismatch: key={key}, organization_id={value.organization_id}")
            validated[key] = value

        return validated
