"""Tests for the Thing class."""

from mudlib.entity import Entity
from mudlib.object import Object
from mudlib.thing import Thing
from mudlib.zone import Zone

# --- construction ---


def test_thing_creation_minimal():
    """Thing can be created with just a name."""
    t = Thing(name="rock")
    assert t.name == "rock"
    assert t.location is None
    assert t.description == ""
    assert t.portable is True  # default: things are portable


def test_thing_creation_with_description():
    """Thing can have a description."""
    t = Thing(name="sword", description="a rusty iron sword")
    assert t.description == "a rusty iron sword"


def test_thing_creation_non_portable():
    """Thing can be marked as non-portable (fixture, scenery)."""
    t = Thing(name="fountain", portable=False)
    assert t.portable is False


def test_thing_in_zone():
    """Thing can be placed in a zone with coordinates."""
    terrain = [["." for _ in range(10)] for _ in range(10)]
    zone = Zone(name="test", width=10, height=10, terrain=terrain)
    rock = Thing(name="rock", location=zone, x=3, y=7)
    assert rock.location is zone
    assert rock.x == 3
    assert rock.y == 7
    assert rock in zone.contents


def test_thing_in_entity_inventory():
    """Thing can be placed in an entity (inventory)."""
    terrain = [["." for _ in range(10)] for _ in range(10)]
    zone = Zone(name="test", width=10, height=10, terrain=terrain)
    entity = Entity(name="player", location=zone, x=5, y=5)
    sword = Thing(name="sword", location=entity)
    assert sword.location is entity
    assert sword in entity.contents
    # Inventory items don't need coordinates
    assert sword.x is None
    assert sword.y is None


def test_thing_is_subclass_of_object():
    """Thing inherits from Object."""
    t = Thing(name="gem")
    assert isinstance(t, Object)


def test_thing_aliases_default_empty():
    """Thing aliases default to empty list."""
    t = Thing(name="rock")
    assert t.aliases == []


def test_thing_aliases():
    """Thing can have aliases for matching."""
    t = Thing(name="pepsi can", aliases=["can", "pepsi"])
    assert t.aliases == ["can", "pepsi"]


# --- entity.can_accept ---


def test_entity_can_accept_portable_thing():
    """Entity accepts portable things (inventory)."""
    entity = Entity(name="player")
    sword = Thing(name="sword", portable=True)
    assert entity.can_accept(sword) is True


def test_entity_rejects_non_portable_thing():
    """Entity rejects non-portable things."""
    entity = Entity(name="player")
    fountain = Thing(name="fountain", portable=False)
    assert entity.can_accept(fountain) is False


def test_entity_rejects_non_thing():
    """Entity rejects objects that aren't Things."""
    entity = Entity(name="player")
    other = Object(name="abstract")
    assert entity.can_accept(other) is False


# --- zone interaction ---


def test_zone_contents_at_finds_things():
    """Zone.contents_at finds things at a position."""
    terrain = [["." for _ in range(10)] for _ in range(10)]
    zone = Zone(name="test", width=10, height=10, terrain=terrain)
    rock = Thing(name="rock", location=zone, x=5, y=5)
    result = zone.contents_at(5, 5)
    assert rock in result


def test_zone_contents_near_finds_things():
    """Zone.contents_near finds things within range."""
    terrain = [["." for _ in range(10)] for _ in range(10)]
    zone = Zone(name="test", width=10, height=10, terrain=terrain)
    rock = Thing(name="rock", location=zone, x=5, y=5)
    result = zone.contents_near(5, 5, 3)
    assert rock in result
