"""Portal commands for zone transitions."""

from mudlib.commands import CommandDefinition, register
from mudlib.commands.movement import send_nearby_message
from mudlib.player import Player
from mudlib.portal import Portal
from mudlib.zone import Zone
from mudlib.zones import get_zone


async def cmd_enter(player: Player, args: str) -> None:
    """Enter a portal to transition to another zone.

    Args:
        player: The player executing the command
        args: Portal name or alias to enter
    """
    if not args.strip():
        await player.send("Enter what?\r\n")
        return

    zone = player.location
    if not isinstance(zone, Zone):
        await player.send("You are nowhere.\r\n")
        return

    # Find portal at player's position
    portals_here = [
        obj for obj in zone.contents_at(player.x, player.y) if isinstance(obj, Portal)
    ]

    # Match by name or alias (exact match only)
    target_name = args.strip().lower()
    portal = None
    for p in portals_here:
        if p.name.lower() == target_name:
            portal = p
            break
        if target_name in (a.lower() for a in p.aliases):
            portal = p
            break

    if not portal:
        await player.send("You don't see that here.\r\n")
        return

    # Look up target zone
    target_zone = get_zone(portal.target_zone)
    if not target_zone:
        await player.send("The portal doesn't lead anywhere.\r\n")
        return

    # Send departure message to nearby players in old zone
    await send_nearby_message(
        player, player.x, player.y, f"{player.name} enters {portal.name}.\r\n"
    )

    # Move player to target zone
    player.move_to(target_zone, x=portal.target_x, y=portal.target_y)

    # Send arrival message to nearby players in new zone
    await send_nearby_message(
        player,
        player.x,
        player.y,
        f"{player.name} arrives from {portal.name}.\r\n",
    )

    # Show new zone to player
    from mudlib.commands.look import cmd_look

    await cmd_look(player, "")


# Register the enter command
register(CommandDefinition("enter", cmd_enter))
