"""Examine command for detailed object inspection."""

from mudlib.commands import CommandDefinition, register
from mudlib.entity import Entity
from mudlib.player import Player
from mudlib.targeting import find_entity_on_tile, find_in_inventory, find_thing_on_tile
from mudlib.thing import Thing
from mudlib.zone import Zone


async def examine_target(
    player: Player,
    target_name: str,
    *,
    prefer_inventory: bool = True,
) -> None:
    """Resolve and describe a target for examine/look style commands."""
    zone = player.location if isinstance(player.location, Zone) else None

    # look <thing> should prioritize entities/ground; direct examine keeps
    # historical inventory-first behavior.
    ordered_finders = []
    if prefer_inventory:
        ordered_finders.append(lambda: find_in_inventory(target_name, player))
    ordered_finders.append(lambda: find_entity_on_tile(target_name, player))
    if zone is not None:
        ordered_finders.append(
            lambda: find_thing_on_tile(target_name, zone, player.x, player.y)
        )
    if not prefer_inventory:
        ordered_finders.append(lambda: find_in_inventory(target_name, player))

    found: Thing | Entity | None = None
    for finder in ordered_finders:
        found = finder()
        if found is not None:
            break

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

    if isinstance(found, Entity):
        if getattr(found, "description", ""):
            await player.send(f"{found.description}\r\n")
        else:
            await player.send(f"{found.name} is {found.posture}.\r\n")
        return

    desc = getattr(found, "description", "")
    if desc:
        await player.send(f"{desc}\r\n")
    else:
        await player.send("You see nothing special.\r\n")


async def cmd_examine(player: Player, args: str) -> None:
    """Examine an object in detail."""
    if not args.strip():
        await player.send("Examine what?\r\n")
        return

    await examine_target(player, args.strip(), prefer_inventory=True)


register(CommandDefinition("examine", cmd_examine, aliases=["ex"], mode="*"))
