"""
Ontology Taxonomy - Core concept registry and classification.

Manages the set of well-known core concepts that form the
backbone of the ontology hierarchy.
"""

from __future__ import annotations

from typing import Any

from pycharter.wiki.ontology.models import ConceptTier

# =============================================================================
# CORE CONCEPTS REGISTRY
# =============================================================================

# Registry mapping concept name -> {tier, broader, description}
CORE_CONCEPTS: dict[str, dict[str, Any]] = {
    "Entity": {
        "tier": ConceptTier.CORE,
        "broader": None,
        "description": "A uniquely identifiable thing in the domain",
    },
    "Attribute": {
        "tier": ConceptTier.CORE,
        "broader": None,
        "description": "A property or characteristic of an entity",
    },
    "Identifier": {
        "tier": ConceptTier.CORE,
        "broader": "Attribute",
        "description": "A value that uniquely identifies an entity",
    },
    "Temporal": {
        "tier": ConceptTier.CORE,
        "broader": "Attribute",
        "description": "A time-related attribute (date, timestamp, duration)",
    },
    "Monetary": {
        "tier": ConceptTier.CORE,
        "broader": "Attribute",
        "description": "A money-related attribute (amount, currency, price)",
    },
    "Status": {
        "tier": ConceptTier.CORE,
        "broader": "Attribute",
        "description": "A state or lifecycle position of an entity",
    },
    "Metric": {
        "tier": ConceptTier.CORE,
        "broader": "Attribute",
        "description": "A measurable quantity or KPI",
    },
    "Classification": {
        "tier": ConceptTier.CORE,
        "broader": "Attribute",
        "description": "A category, type, or grouping label",
    },
    "Contact": {
        "tier": ConceptTier.CORE,
        "broader": "Attribute",
        "description": "Contact information (email, phone, address)",
    },
    "Geospatial": {
        "tier": ConceptTier.CORE,
        "broader": "Attribute",
        "description": "Location or geographic information",
    },
}


def register_core_concept(
    name: str,
    tier: ConceptTier,
    broader: str | None = None,
    description: str = "",
) -> None:
    """
    Register a new core concept in the taxonomy.

    Args:
        name: Concept name
        tier: Governance tier
        broader: Parent concept name (optional)
        description: Human-readable description
    """
    CORE_CONCEPTS[name] = {
        "tier": tier,
        "broader": broader,
        "description": description,
    }


def list_core_concepts() -> list[dict[str, Any]]:
    """
    List all registered core concepts.

    Returns:
        List of dicts with name, tier, broader, description.
    """
    return [
        {
            "name": name,
            "tier": info["tier"].value,
            "broader": info["broader"],
            "description": info["description"],
        }
        for name, info in CORE_CONCEPTS.items()
    ]


def classify_concept(concept_name: str) -> ConceptTier:
    """
    Classify a concept into a governance tier.

    Core concepts get their registered tier. Unknown concepts
    are classified as free-form (Tier 3).

    Args:
        concept_name: Name of the concept

    Returns:
        The governance tier for this concept
    """
    if concept_name in CORE_CONCEPTS:
        return CORE_CONCEPTS[concept_name]["tier"]
    return ConceptTier.FREE


def get_concept_hierarchy() -> dict[str, Any]:
    """
    Build a tree of the core concept hierarchy.

    Returns:
        Nested dict representing the concept tree.
        Each node has 'name', 'tier', 'description', and 'children'.
    """
    # Build parent -> children mapping
    children_map: dict[str | None, list[str]] = {}
    for name, info in CORE_CONCEPTS.items():
        parent = info["broader"]
        if parent not in children_map:
            children_map[parent] = []
        children_map[parent].append(name)

    def build_node(name: str) -> dict[str, Any]:
        info = CORE_CONCEPTS[name]
        node: dict[str, Any] = {
            "name": name,
            "tier": info["tier"].value,
            "description": info["description"],
            "children": [],
        }
        if name in children_map:
            node["children"] = [
                build_node(child) for child in sorted(children_map[name])
            ]
        return node

    # Root nodes are those with no broader (broader=None)
    roots = children_map.get(None, [])
    return {
        "roots": [build_node(root) for root in sorted(roots)],
    }
