"""Base entity class for characters in the world."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import TYPE_CHECKING

from mudlib.object import Object

if TYPE_CHECKING:
    from mudlib.npc_schedule import NpcSchedule


@dataclass(eq=False)
class Entity(Object):
    """Base class for anything with position and identity in the world.

    Inherits name, location from Object. Narrows x, y to int (entities
    always have spatial coordinates).
    """

    # Entities always have spatial coordinates (override Object's int | None)
    x: int = 0
    y: int = 0
    # Combat stats
    pl: float = 100.0  # power level (health and damage multiplier)
    max_pl: float = 100.0  # maximum power level
    stamina: float = 100.0  # current stamina
    max_stamina: float = 100.0  # stamina ceiling
    defense_locked_until: float = 0.0  # monotonic time when defense recovery ends
    resting: bool = False  # whether this entity is currently resting
    sleeping: bool = False  # whether this entity is currently sleeping (deep rest)
    _last_stamina_cue: float = 1.0  # Last stamina percentage that triggered a cue

    @property
    def posture(self) -> str:
        """Return entity's current posture for room display.

        Priority order: unconscious > fighting > flying > sleeping > resting > standing
        """
        # Unconscious (highest priority)
        if self.pl <= 0 or self.stamina <= 0:
            return "unconscious"

        # Fighting (only for Player with mode="combat")
        if hasattr(self, "mode") and self.mode == "combat":
            return "fighting"

        # Flying (only for Player)
        if getattr(self, "flying", False):
            return "flying"

        # Sleeping (before resting since sleeping implies resting)
        if self.sleeping:
            return "sleeping"

        # Resting
        if self.resting:
            return "resting"

        # Default
        return "standing"

    def can_accept(self, obj: Object) -> bool:
        """Entities accept portable Things (inventory)."""
        from mudlib.thing import Thing

        return isinstance(obj, Thing) and obj.portable

    async def send(self, message: str) -> None:
        """Send a message to this entity. Base implementation is a no-op."""
        pass


@dataclass(eq=False)
class Mob(Entity):
    """Represents a non-player character (NPC) in the world."""

    description: str = ""
    alive: bool = True
    moves: list[str] = field(default_factory=list)
    next_action_at: float = 0.0
    home_x_min: int | None = None
    home_x_max: int | None = None
    home_y_min: int | None = None
    home_y_max: int | None = None
    # NPC behavior state machine
    behavior_state: str = "idle"
    behavior_data: dict = field(default_factory=dict)
    npc_name: str | None = None  # links to dialogue tree
    schedule: NpcSchedule | None = None  # time-based behavior schedule
    schedule_last_hour: int | None = None  # last hour schedule was processed
