"""Canonical data types for world interaction.

These mirror the PerceptionOutput / CommandInput types from PR #864's
``morrowind/schemas.py``.  When that PR merges, these can be replaced
with re-exports — but until then they serve as the stable contract for
every WorldInterface adapter.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import UTC, datetime
from enum import StrEnum


class ActionStatus(StrEnum):
    """Outcome of an action dispatched to the world."""

    SUCCESS = "success"
    FAILURE = "failure"
    PENDING = "pending"
    NOOP = "noop"


@dataclass
class PerceptionOutput:
    """Structured world state returned by ``WorldInterface.observe()``.

    Attributes:
        timestamp:  When the observation was captured.
        location:   Free-form location descriptor (e.g. "Balmora, Fighters Guild").
        entities:   List of nearby entity descriptions.
        events:     Recent game events since last observation.
        raw:        Optional raw / engine-specific payload for advanced consumers.
    """

    timestamp: datetime = field(default_factory=lambda: datetime.now(UTC))
    location: str = ""
    entities: list[str] = field(default_factory=list)
    events: list[str] = field(default_factory=list)
    raw: dict = field(default_factory=dict)


@dataclass
class CommandInput:
    """Action command sent via ``WorldInterface.act()``.

    Attributes:
        action:     Verb / action name (e.g. "move", "attack", "use_item").
        target:     Optional target identifier.
        parameters: Arbitrary key-value payload for engine-specific params.
    """

    action: str
    target: str | None = None
    parameters: dict = field(default_factory=dict)


@dataclass
class ActionResult:
    """Outcome returned by ``WorldInterface.act()``.

    Attributes:
        status:   Whether the action succeeded, failed, etc.
        message:  Human-readable description of the outcome.
        data:     Arbitrary engine-specific result payload.
    """

    status: ActionStatus = ActionStatus.SUCCESS
    message: str = ""
    data: dict = field(default_factory=dict)
