"""Builder commands for world editing."""

from pathlib import Path

from mudlib.commands import CommandDefinition, register
from mudlib.export import export_zone_to_file
from mudlib.player import Player
from mudlib.things import spawn_thing, thing_templates
from mudlib.zone import Zone
from mudlib.zones import get_zone, register_zone

# Content directory, set during server startup
_content_dir: Path | None = None


def set_content_dir(path: Path) -> None:
    """Set the content directory for saving zones."""
    global _content_dir
    _content_dir = path


async def cmd_goto(player: Player, args: str) -> None:
    """Teleport to a named zone's spawn point."""
    zone_name = args.strip()
    if not zone_name:
        await player.send("Usage: @goto <zone_name>\r\n")
        return

    target = get_zone(zone_name)
    if target is None:
        await player.send(f"Zone '{zone_name}' not found.\r\n")
        return

    player.move_to(target, x=target.spawn_x, y=target.spawn_y)
    await player.send(f"Teleported to {zone_name}.\r\n")

    from mudlib.commands.look import cmd_look

    await cmd_look(player, "")


async def cmd_dig(player: Player, args: str) -> None:
    """Create a new blank zone and teleport there."""
    parts = args.strip().split()
    if len(parts) != 3:
        await player.send("Usage: @dig <name> <width> <height>\r\n")
        return

    name = parts[0]
    try:
        width = int(parts[1])
        height = int(parts[2])
    except ValueError:
        await player.send("Width and height must be numbers.\r\n")
        return

    if width < 1 or height < 1:
        await player.send("Zone dimensions must be at least 1x1.\r\n")
        return

    if get_zone(name) is not None:
        await player.send(f"Zone '{name}' already exists.\r\n")
        return

    terrain = [["." for _ in range(width)] for _ in range(height)]
    zone = Zone(
        name=name,
        width=width,
        height=height,
        terrain=terrain,
        toroidal=False,
    )
    register_zone(name, zone)

    player.move_to(zone, x=0, y=0)
    await player.send(f"Created zone '{name}' ({width}x{height}).\r\n")

    from mudlib.commands.look import cmd_look

    await cmd_look(player, "")


async def cmd_save(player: Player, args: str) -> None:
    """Save the current zone to its TOML file."""
    zone = player.location
    if not isinstance(zone, Zone):
        await player.send("You're not in a zone.\r\n")
        return

    if _content_dir is None:
        await player.send("Content directory not configured.\r\n")
        return

    zones_dir = _content_dir / "zones"
    zones_dir.mkdir(parents=True, exist_ok=True)
    path = zones_dir / f"{zone.name}.toml"
    export_zone_to_file(zone, path)
    await player.send(f"Zone '{zone.name}' saved to {path.name}.\r\n")


async def cmd_place(player: Player, args: str) -> None:
    """Place a thing from templates at the player's position."""
    thing_name = args.strip()
    if not thing_name:
        await player.send("Usage: @place <thing_name>\r\n")
        return

    template = thing_templates.get(thing_name)
    if template is None:
        await player.send(f"Thing template '{thing_name}' not found.\r\n")
        return

    spawn_thing(template, player.location, x=player.x, y=player.y)
    await player.send(f"Placed {thing_name} at ({player.x}, {player.y}).\r\n")


register(CommandDefinition("@goto", cmd_goto, admin=True, help="Teleport to a zone"))
register(CommandDefinition("@dig", cmd_dig, admin=True, help="Create a new zone"))
register(CommandDefinition("@save", cmd_save, admin=True, help="Save current zone"))
register(CommandDefinition("@place", cmd_place, admin=True, help="Place a thing"))
