"""Standardized game event model and event vocabulary.

Defines the GameEvent frozen dataclass and a vocabulary of standard event
types that all game adapters map into. Users configure effects against these
universal categories, so a "health < 30% -> flash red" config works across
any supported game.
"""

import time
from dataclasses import dataclass, field
from enum import Enum
from typing import Any


class EventCategory(str, Enum):
    """Top-level grouping for event types."""

    RESOURCE = "resource"
    COMBAT = "combat"
    MATCH_FLOW = "match_flow"
    OBJECTIVE = "objective"
    STATUS_EFFECT = "status_effect"
    TEAM = "team"


class ValueType(str, Enum):
    """Whether an event carries a continuous value or is a discrete trigger."""

    CONTINUOUS = "continuous"
    TRIGGER = "trigger"


@dataclass(frozen=True)
class EventTypeMetadata:
    """Metadata describing a standard event type."""

    name: str
    display_name: str
    category: EventCategory
    value_type: ValueType
    default_min: float = 0.0
    default_max: float = 1.0


# ── Standard Event Vocabulary ────────────────────────────────────────────

_VOCABULARY: dict[str, EventTypeMetadata] = {}


def _reg(
    name: str,
    display_name: str,
    category: EventCategory,
    value_type: ValueType,
    default_min: float = 0.0,
    default_max: float = 1.0,
) -> str:
    """Register an event type in the vocabulary and return its name."""
    _VOCABULARY[name] = EventTypeMetadata(
        name=name,
        display_name=display_name,
        category=category,
        value_type=value_type,
        default_min=default_min,
        default_max=default_max,
    )
    return name


# Resource (continuous)
HEALTH = _reg("health", "Health", EventCategory.RESOURCE, ValueType.CONTINUOUS)
ARMOR = _reg("armor", "Armor", EventCategory.RESOURCE, ValueType.CONTINUOUS)
SHIELD = _reg("shield", "Shield", EventCategory.RESOURCE, ValueType.CONTINUOUS)
MANA = _reg("mana", "Mana", EventCategory.RESOURCE, ValueType.CONTINUOUS)
ENERGY = _reg("energy", "Energy", EventCategory.RESOURCE, ValueType.CONTINUOUS)
AMMO = _reg("ammo", "Ammo", EventCategory.RESOURCE, ValueType.CONTINUOUS)
GOLD = _reg("gold", "Gold", EventCategory.RESOURCE, ValueType.CONTINUOUS)
FUEL = _reg("fuel", "Fuel", EventCategory.RESOURCE, ValueType.CONTINUOUS)
SPEED = _reg("speed", "Speed", EventCategory.RESOURCE, ValueType.CONTINUOUS)

# Combat (triggers)
KILL = _reg("kill", "Kill", EventCategory.COMBAT, ValueType.TRIGGER)
DEATH = _reg("death", "Death", EventCategory.COMBAT, ValueType.TRIGGER)
ASSIST = _reg("assist", "Assist", EventCategory.COMBAT, ValueType.TRIGGER)
DAMAGE_TAKEN = _reg("damage_taken", "Damage Taken", EventCategory.COMBAT, ValueType.TRIGGER)
DAMAGE_DEALT = _reg("damage_dealt", "Damage Dealt", EventCategory.COMBAT, ValueType.TRIGGER)

# Match flow (triggers)
MATCH_START = _reg("match_start", "Match Start", EventCategory.MATCH_FLOW, ValueType.TRIGGER)
MATCH_END = _reg("match_end", "Match End", EventCategory.MATCH_FLOW, ValueType.TRIGGER)
ROUND_START = _reg("round_start", "Round Start", EventCategory.MATCH_FLOW, ValueType.TRIGGER)
ROUND_END = _reg("round_end", "Round End", EventCategory.MATCH_FLOW, ValueType.TRIGGER)

# Objective
OBJECTIVE_CAPTURED = _reg(
    "objective_captured",
    "Objective Captured",
    EventCategory.OBJECTIVE,
    ValueType.TRIGGER,
)
OBJECTIVE_LOST = _reg(
    "objective_lost",
    "Objective Lost",
    EventCategory.OBJECTIVE,
    ValueType.TRIGGER,
)
OBJECTIVE_PROGRESS = _reg(
    "objective_progress",
    "Objective Progress",
    EventCategory.OBJECTIVE,
    ValueType.CONTINUOUS,
)

# Status effects (triggers)
STUNNED = _reg("stunned", "Stunned", EventCategory.STATUS_EFFECT, ValueType.TRIGGER)
BLINDED = _reg("blinded", "Blinded", EventCategory.STATUS_EFFECT, ValueType.TRIGGER)
BUFFED = _reg("buffed", "Buffed", EventCategory.STATUS_EFFECT, ValueType.TRIGGER)
DEBUFFED = _reg("debuffed", "Debuffed", EventCategory.STATUS_EFFECT, ValueType.TRIGGER)

# Team affiliation (continuous — e.g. team score)
TEAM_A = _reg("team_a", "Team A", EventCategory.TEAM, ValueType.CONTINUOUS)
TEAM_B = _reg("team_b", "Team B", EventCategory.TEAM, ValueType.CONTINUOUS)


def get_event_vocabulary() -> dict[str, EventTypeMetadata]:
    """Return a copy of the full event vocabulary."""
    return dict(_VOCABULARY)


def get_event_metadata(event_type: str) -> EventTypeMetadata | None:
    """Look up metadata for a standard event type."""
    return _VOCABULARY.get(event_type)


def is_known_event_type(event_type: str) -> bool:
    """Check whether an event type is in the standard vocabulary."""
    return event_type in _VOCABULARY


# ── GameEvent dataclass ──────────────────────────────────────────────────


@dataclass(frozen=True)
class GameEvent:
    """A single game event emitted by an adapter.

    Attributes:
        adapter_id: Identifier of the adapter that produced this event.
        event_type: Standard event type string from the vocabulary.
        value: Normalized value in 0.0-1.0 range (1.0 for triggers).
        raw_data: Original game-specific data for debugging.
        timestamp: Monotonic timestamp (time.monotonic()).
    """

    adapter_id: str
    event_type: str
    value: float = 1.0
    raw_data: dict[str, Any] = field(default_factory=dict)
    timestamp: float = field(default_factory=time.monotonic)
