"""Bundle and licensing boundary validation — Phase 11.8."""
from typing import Any

from app.validators.foundation import ValidationError, validate_non_empty
from shared.exceptions import AppError

FORBIDDEN_OWNERSHIP_KEYS = frozenset(
    {"plan_engine", "subscription_engine", "billing_ledger", "core_plan_id"}
)


def validate_metadata(value: Any) -> dict | None:
    if value is None:
        return None
    if not isinstance(value, dict):
        raise ValidationError("metadata_json باید object باشد", {"field": "metadata_json"})
    banned = FORBIDDEN_OWNERSHIP_KEYS.intersection(value)
    if banned:
        raise ValidationError(
            "مالکیت plan/subscription/billing متعلق به Core است",
            {"field": "metadata_json", "forbidden_keys": sorted(banned)},
        )
    return value


def validate_entitlement_ref(value: str | None, *, required: bool = False) -> str | None:
    if value is None:
        if required:
            raise ValidationError("core_entitlement_ref الزامی است")
        return None
    cleaned = validate_non_empty(value, "core_entitlement_ref")
    if len(cleaned) > 255:
        raise ValidationError("core_entitlement_ref بیش از حد طولانی است")
    return cleaned


def ensure_transition(current, target, transitions: dict, label: str) -> None:
    if current == target:
        return
    if target not in transitions.get(current, frozenset()):
        raise AppError(
            f"گذار وضعیت {label} مجاز نیست",
            error_code=f"invalid_{label}_status_transition",
            status_code=409,
            details={"current": current.value, "target": target.value},
        )
