"""Tests for room rendering functions."""

from mudlib.entity import Mob
from mudlib.render.room import (
    render_entity_lines,
    render_exits,
    render_location,
    render_nearby,
    render_where,
)
from mudlib.zone import Zone


def test_render_where():
    """render_where returns 'Where: {zone description}'."""
    zone = Zone(name="overworld", description="The Overworld")
    assert render_where(zone.description) == "Where: The Overworld"

    zone2 = Zone(name="cave", description="Dark Cave")
    assert render_where(zone2.description) == "Where: Dark Cave"


def test_render_location_center():
    """render_location shows 'center' for positions near zone center."""
    zone = Zone(name="test", width=50, height=50, terrain=[])
    # Center should be around 25, 25 (middle third of both axes)
    assert render_location(zone, 25, 25) == "Location: center 25, 25"
    assert render_location(zone, 20, 20) == "Location: center 20, 20"
    assert render_location(zone, 30, 30) == "Location: center 30, 30"


def test_render_location_quadrants():
    """render_location shows correct quadrants based on position."""
    zone = Zone(name="test", width=60, height=60, terrain=[])
    # Thirds: 0-19 west/north, 20-39 center, 40-59 east/south

    # Northwest
    assert render_location(zone, 5, 5) == "Location: northwest 5, 5"
    assert render_location(zone, 10, 10) == "Location: northwest 10, 10"

    # North (center horizontally, north vertically)
    assert render_location(zone, 30, 5) == "Location: north 30, 5"

    # Northeast
    assert render_location(zone, 50, 5) == "Location: northeast 50, 5"

    # West (west horizontally, center vertically)
    assert render_location(zone, 5, 30) == "Location: west 5, 30"

    # East
    assert render_location(zone, 50, 30) == "Location: east 50, 30"

    # Southwest
    assert render_location(zone, 5, 50) == "Location: southwest 5, 50"

    # South
    assert render_location(zone, 30, 50) == "Location: south 30, 50"

    # Southeast
    assert render_location(zone, 50, 50) == "Location: southeast 50, 50"


def test_render_nearby_empty():
    """render_nearby returns empty string when no nearby entities."""
    assert render_nearby([], None) == ""


def test_render_nearby_single():
    """render_nearby shows count and single entity name."""
    mob = Mob(name="saibaman", x=10, y=10)
    result = render_nearby([mob], None)
    assert result == "Nearby: (1) saibaman"


def test_render_nearby_multiple():
    """render_nearby shows count and names separated by '/'."""
    mobs = [
        Mob(name="saibaman", x=10, y=10),
        Mob(name="Master Roshi", x=11, y=10),
        Mob(name="Goku", x=10, y=11),
    ]
    result = render_nearby(mobs, None)
    assert result == "Nearby: (3) saibaman / Master Roshi / Goku"


def test_render_exits_all_directions():
    """render_exits shows all passable cardinal directions."""
    # Create zone with all passable terrain (grass)
    terrain = [["." for _ in range(10)] for _ in range(10)]
    zone = Zone(
        name="test", width=10, height=10, terrain=terrain, impassable={"^", "~"}
    )

    result = render_exits(zone, 5, 5)
    assert result == "Exits: north south east west"


def test_render_exits_blocked_directions():
    """render_exits only shows passable directions."""
    # Create zone with mountains (^) blocking some directions
    terrain = [
        [".", ".", ".", ".", "."],
        [".", ".", "^", ".", "."],  # mountain north
        [".", "^", ".", "^", "."],  # mountains west and east
        [".", ".", "^", ".", "."],  # mountain south
        [".", ".", ".", ".", "."],
    ]
    zone = Zone(name="test", width=5, height=5, terrain=terrain, impassable={"^", "~"})

    # Position at center (2, 2) — surrounded by mountains
    result = render_exits(zone, 2, 2)
    assert result == "Exits:"  # no passable exits


def test_render_exits_partial():
    """render_exits shows only available exits."""
    terrain = [
        [".", ".", "."],
        ["^", ".", "."],  # mountain to west
        [".", "^", "."],  # mountain to south
    ]
    zone = Zone(name="test", width=3, height=3, terrain=terrain, impassable={"^"})

    # Position at (1, 1) — north and east are passable
    result = render_exits(zone, 1, 1)
    assert result == "Exits: north east"


def test_render_entity_lines_empty():
    """render_entity_lines returns empty string when no entities."""
    assert render_entity_lines([], None) == ""


def test_render_entity_lines_single():
    """render_entity_lines shows single entity with posture."""
    mob = Mob(name="saibaman", x=10, y=10)
    # Default posture is "standing" (fallback)
    result = render_entity_lines([mob], None)
    assert result == "saibaman is standing here."


def test_render_entity_lines_multiple():
    """render_entity_lines shows multiple entities, each on own line."""
    # Create entities with different states that affect posture
    mob1 = Mob(name="saibaman", x=10, y=10)  # standing by default
    mob2 = Mob(name="Master Roshi", x=10, y=10, resting=True)  # resting

    result = render_entity_lines([mob1, mob2], None)
    lines = result.split("\n")
    assert len(lines) == 2
    assert lines[0] == "saibaman is standing here."
    assert lines[1] == "Master Roshi is resting here."


def test_render_entity_lines_postures():
    """render_entity_lines handles different posture types based on entity state."""
    # Standing (default state)
    mob = Mob(name="Goku", x=10, y=10)
    assert render_entity_lines([mob], None) == "Goku is standing here."

    # Resting (resting=True)
    mob_resting = Mob(name="Goku", x=10, y=10, resting=True)
    assert render_entity_lines([mob_resting], None) == "Goku is resting here."

    # Unconscious (pl <= 0)
    mob_unconscious = Mob(name="Goku", x=10, y=10, pl=0)
    assert render_entity_lines([mob_unconscious], None) == "Goku is unconscious."

    # Unconscious (stamina <= 0)
    mob_exhausted = Mob(name="Goku", x=10, y=10, stamina=0)
    assert render_entity_lines([mob_exhausted], None) == "Goku is unconscious."
