from __future__ import annotations

import re
from typing import Any

try:
    from . import category_template_metadata as template_metadata_policy
    from .hardcore_action_metadata import normalize_hardcore_action_family
    from .hardcore_position_config import normalize_hardcore_position_family, normalize_hardcore_position_values
except ImportError:  # Allows local smoke tests from the repository root.
    import category_template_metadata as template_metadata_policy
    from hardcore_action_metadata import normalize_hardcore_action_family
    from hardcore_position_config import normalize_hardcore_position_family, normalize_hardcore_position_values


def row_action_family(row: Any, default: str = "") -> str:
    if not isinstance(row, dict):
        return default
    family = normalize_hardcore_action_family(row.get("action_family"), "")
    if family:
        return family
    metadata = row.get("item_template_metadata")
    if isinstance(metadata, dict):
        family = template_metadata_policy.template_action_family(metadata)
        if family:
            return family
    return default


def row_position_family(row: Any, default: str = "") -> str:
    if not isinstance(row, dict):
        return default
    family = normalize_hardcore_position_family(str(row.get("position_family") or "").strip().lower(), "")
    if family:
        return family
    metadata = row.get("item_template_metadata")
    if isinstance(metadata, dict):
        family = template_metadata_policy.template_position_family(metadata)
        if family:
            return family
    return default


def _raw_position_key_values(row: dict[str, Any]) -> list[Any]:
    values: list[Any] = []
    position_keys = row.get("position_keys")
    if isinstance(position_keys, list):
        values.extend(position_keys)
    elif position_keys is not None:
        values.append(position_keys)
    if row.get("position_key") is not None:
        values.append(row.get("position_key"))
    return values


def _position_key_slug(value: Any) -> str:
    text = str(value or "").strip()
    if not text or text == "any":
        return ""
    return re.sub(r"[^a-z0-9]+", "_", text.lower()).strip("_")


def row_position_keys(row: Any, *, include_unknown: bool = False) -> list[str]:
    if not isinstance(row, dict):
        return []
    values = _raw_position_key_values(row)
    selected = normalize_hardcore_position_values(values)
    metadata = row.get("item_template_metadata")
    if isinstance(metadata, dict):
        for key in template_metadata_policy.template_position_keys(metadata):
            if key and key not in selected:
                selected.append(key)
    if not include_unknown:
        return selected
    for value in values:
        normalized = _position_key_slug(value)
        if normalized and normalized not in selected:
            selected.append(normalized)
    return selected


def row_formatter_hints(row: Any, route: str) -> list[str]:
    hints: list[str] = []
    for hint in template_metadata_policy.formatter_hints_for_route(row, route):
        if hint not in hints:
            hints.append(hint)
    if isinstance(row, dict) and isinstance(row.get("item_template_metadata"), dict):
        for hint in template_metadata_policy.formatter_hints_for_route(row["item_template_metadata"], route):
            if hint not in hints:
                hints.append(hint)
    return hints
