from typing import Any, Optional

from semantic_models.schemas import DistinctValuesHandlingMode, SemanticModelSpec
from semantic_models.services.semantic_models_service import Version


def get_sample_limit(attr: Any) -> Optional[int]:
    """Extract autoValuesLimit from an attribute sqlGenerationConfig."""
    cfg: dict | None = None
    if isinstance(attr, dict):
        cfg = attr.get("sqlGenerationConfig")
    else:
        cfg = getattr(attr, "sqlGenerationConfig", None)
    if not isinstance(cfg, dict):
        return None
    raw_limit = cfg.get("autoValuesLimit")
    if not isinstance(raw_limit, int) or raw_limit <= 0:
        return None
    return raw_limit


def _get_attr_field(attr: Any, field_name: str) -> Any:
    if isinstance(attr, dict):
        return attr.get(field_name)
    return getattr(attr, field_name, None)


def get_distinct_values_mode(attr: Any) -> Optional[str]:
    """Return normalized distinct values mode (MANUAL/AUTO_INDEX/NONE)."""
    raw_mode = _get_attr_field(attr, "distinctValuesHandlingMode")
    if raw_mode is None:
        return None

    if hasattr(raw_mode, "value"):
        raw_mode = raw_mode.value

    if not isinstance(raw_mode, str):
        return None

    return raw_mode.strip().upper()


def has_manual_values(attr: Any) -> bool:
    values = _get_attr_field(attr, "manualValues")
    return isinstance(values, list) and len(values) > 0


def is_auto_values_enabled(attr: Any) -> bool:
    mode = get_distinct_values_mode(attr)
    return mode == DistinctValuesHandlingMode.AUTO_INDEX.value


def should_use_distinct_values(attr: Any) -> bool:
    """True when attribute should contribute value examples/indexing."""
    mode = get_distinct_values_mode(attr)
    if mode == DistinctValuesHandlingMode.MANUAL.value:
        return has_manual_values(attr)
    return mode == DistinctValuesHandlingMode.AUTO_INDEX.value


def build_spec_from_version(version: Version | dict) -> SemanticModelSpec:
    if isinstance(version, dict):
        entities = version.get("entities", [])
        relationships = version.get("relationships", [])
        sql_generation_config = version.get("sqlGenerationConfig") or {}
        instructions = sql_generation_config.get("instructions")
    else:
        entities = version.entities
        relationships = version.relationships
        sql_generation_config = version.sqlGenerationConfig or {}
        instructions = sql_generation_config.get("instructions")
    return SemanticModelSpec.model_validate(
        {
            "entities": entities,
            "relationships": relationships,
            "instructions": instructions,
        }
    )
