"""Tests for two-way portal transitions."""

from unittest.mock import AsyncMock, MagicMock

import pytest

from mudlib.player import Player
from mudlib.portal import Portal
from mudlib.zone import Zone
from mudlib.zones import register_zone, zone_registry


@pytest.fixture
def mock_writer():
    writer = MagicMock()
    writer.write = MagicMock()
    writer.drain = AsyncMock()
    return writer


@pytest.fixture
def mock_reader():
    return MagicMock()


@pytest.fixture
def zone_a():
    terrain = [["." for _ in range(10)] for _ in range(10)]
    return Zone(
        name="zone_a",
        width=10,
        height=10,
        toroidal=True,
        terrain=terrain,
    )


@pytest.fixture
def zone_b():
    terrain = [["." for _ in range(10)] for _ in range(10)]
    return Zone(
        name="zone_b",
        width=10,
        height=10,
        toroidal=True,
        terrain=terrain,
    )


@pytest.fixture
def player(mock_reader, mock_writer, zone_a):
    p = Player(
        name="TestPlayer",
        x=2,
        y=2,
        reader=mock_reader,
        writer=mock_writer,
        location=zone_a,
    )
    return p


@pytest.fixture(autouse=True)
def clear_zones():
    """Clear zone registry before and after each test."""
    zone_registry.clear()
    yield
    zone_registry.clear()


@pytest.mark.asyncio
async def test_two_way_portal_transitions(player, zone_a, zone_b):
    """Portals work bidirectionally between zones."""
    from mudlib.commands.portals import cmd_enter

    # Register zones
    register_zone("zone_a", zone_a)
    register_zone("zone_b", zone_b)

    # Create portal in zone A pointing to zone B
    Portal(
        name="doorway to B",
        location=zone_a,
        x=2,
        y=2,
        target_zone="zone_b",
        target_x=7,
        target_y=7,
    )

    # Create portal in zone B pointing to zone A
    Portal(
        name="doorway to A",
        location=zone_b,
        x=7,
        y=7,
        target_zone="zone_a",
        target_x=2,
        target_y=2,
    )

    # Player starts in zone A at (2, 2)
    assert player.location is zone_a
    assert player.x == 2
    assert player.y == 2

    # Enter portal to zone B
    await cmd_enter(player, "doorway to B")
    assert player.location is zone_b
    assert player.x == 7
    assert player.y == 7

    # Enter portal back to zone A
    await cmd_enter(player, "doorway to A")
    assert player.location is zone_a
    assert player.x == 2
    assert player.y == 2
