"""Reload command for hot-reloading TOML content definitions."""

import logging
from pathlib import Path

from mudlib.commands import CommandDefinition, register
from mudlib.player import Player

log = logging.getLogger(__name__)


async def cmd_reload(player: Player, args: str) -> None:
    """Reload a TOML content definition by name.

    Args:
        player: The player executing the command
        args: Name of the content to reload (e.g. "punch", "motd")
    """
    args = args.strip()

    if not args:
        await player.send("Usage: reload <name>\r\n")
        return

    # Try combat move first
    combat_reloaded = await _try_reload_combat(player, args)
    if combat_reloaded:
        return

    # Try content command
    command_reloaded = await _try_reload_command(player, args)
    if command_reloaded:
        return

    # Not found in either location
    await player.send(f"No content found with name: {args}\r\n")


async def _try_reload_combat(player: Player, name: str) -> bool:
    """Try to reload a combat move TOML.

    Args:
        player: The player executing the reload
        name: Base name of the move (e.g. "punch")

    Returns:
        True if the reload succeeded, False if the file doesn't exist
    """
    from mudlib.combat.commands import combat_content_dir, combat_moves, register_moves
    from mudlib.combat.moves import load_move
    from mudlib.commands import unregister

    if combat_content_dir is None:
        return False

    toml_path = combat_content_dir / f"{name}.toml"
    if not toml_path.exists():
        return False

    try:
        # Load the new move definitions
        new_moves = load_move(toml_path)

        # Unregister old command entries from registry
        # For variant moves, unregister the base command (e.g. "punch")
        # For simple moves, unregister the move name (e.g. "roundhouse")
        if new_moves and new_moves[0].variant:
            # Variant move - unregister base command
            unregister(new_moves[0].command)
        else:
            # Simple move - unregister each move name
            for move in new_moves:
                unregister(move.name)

        # Remove old entries from combat_moves dict
        # Need to remove all variants and aliases
        keys_to_remove = []
        for key, move in combat_moves.items():
            if move.command == name:
                keys_to_remove.append(key)

        for key in keys_to_remove:
            del combat_moves[key]

        # Add new moves to combat_moves dict
        for move in new_moves:
            combat_moves[move.name] = move
            for alias in move.aliases:
                combat_moves[alias] = move

        # Re-register commands using shared logic
        register_moves(new_moves)

        await player.send(f"Reloaded combat move: {name}\r\n")
        return True

    except Exception as e:
        log.exception("Failed to reload combat move %s", name)
        await player.send(f"Failed to reload {name}: {e}\r\n")
        return True


async def _try_reload_command(player: Player, name: str) -> bool:
    """Try to reload a content command TOML.

    Args:
        player: The player executing the reload
        name: Name of the command (e.g. "motd")

    Returns:
        True if the reload succeeded, False if the file doesn't exist
    """
    from mudlib.commands import unregister
    from mudlib.content import load_command

    # Find content directory
    content_dir = Path(__file__).resolve().parents[2] / "content" / "commands"
    toml_path = content_dir / f"{name}.toml"

    if not toml_path.exists():
        return False

    try:
        # Load the new command definition
        cmd_def = load_command(toml_path)

        # Unregister old command entry before re-registering
        unregister(cmd_def.name)

        # Register the new definition
        register(cmd_def)

        await player.send(f"Reloaded command: {name}\r\n")
        return True

    except Exception as e:
        log.exception("Failed to reload command %s", name)
        await player.send(f"Failed to reload {name}: {e}\r\n")
        return True


# Register the reload command
register(CommandDefinition("reload", cmd_reload, mode="normal", help="reload a TOML"))
