"""Tests for thing template loading and spawning."""

import textwrap

import pytest

from mudlib.thing import Thing
from mudlib.things import (
    ThingTemplate,
    load_thing_template,
    load_thing_templates,
    spawn_thing,
)
from mudlib.zone import Zone


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


# --- ThingTemplate ---


def test_thing_template_creation():
    """ThingTemplate holds definition data."""
    t = ThingTemplate(
        name="rock",
        description="a smooth grey rock",
        portable=True,
        aliases=["stone"],
    )
    assert t.name == "rock"
    assert t.description == "a smooth grey rock"
    assert t.portable is True
    assert t.aliases == ["stone"]


def test_thing_template_defaults():
    """ThingTemplate has sensible defaults."""
    t = ThingTemplate(name="rock", description="a rock")
    assert t.portable is True
    assert t.aliases == []


# --- load_thing_template ---


def test_load_thing_template(tmp_path):
    """Load a thing template from a TOML file."""
    toml_content = textwrap.dedent("""\
        name = "rusty sword"
        description = "a sword covered in rust"
        portable = true
        aliases = ["sword", "rusty"]
    """)
    p = tmp_path / "sword.toml"
    p.write_text(toml_content)

    template = load_thing_template(p)
    assert template.name == "rusty sword"
    assert template.description == "a sword covered in rust"
    assert template.portable is True
    assert template.aliases == ["sword", "rusty"]


def test_load_thing_template_minimal(tmp_path):
    """Load thing template with only required fields."""
    toml_content = textwrap.dedent("""\
        name = "rock"
        description = "a rock"
    """)
    p = tmp_path / "rock.toml"
    p.write_text(toml_content)

    template = load_thing_template(p)
    assert template.name == "rock"
    assert template.portable is True  # default
    assert template.aliases == []  # default


def test_load_thing_template_non_portable(tmp_path):
    """Load a non-portable thing template."""
    toml_content = textwrap.dedent("""\
        name = "fountain"
        description = "a stone fountain"
        portable = false
    """)
    p = tmp_path / "fountain.toml"
    p.write_text(toml_content)

    template = load_thing_template(p)
    assert template.portable is False


# --- load_thing_templates ---


def test_load_thing_templates(tmp_path):
    """Load all thing templates from a directory."""
    for name in ["rock", "sword"]:
        p = tmp_path / f"{name}.toml"
        p.write_text(f'name = "{name}"\ndescription = "a {name}"\n')

    templates = load_thing_templates(tmp_path)
    assert "rock" in templates
    assert "sword" in templates
    assert len(templates) == 2


def test_load_thing_templates_empty_dir(tmp_path):
    """Empty directory returns empty dict."""
    templates = load_thing_templates(tmp_path)
    assert templates == {}


# --- spawn_thing ---


def test_spawn_thing_in_zone(test_zone):
    """spawn_thing creates a Thing instance in a zone."""
    template = ThingTemplate(
        name="rock",
        description="a smooth grey rock",
        portable=True,
        aliases=["stone"],
    )
    thing = spawn_thing(template, test_zone, x=3, y=7)
    assert isinstance(thing, Thing)
    assert thing.name == "rock"
    assert thing.description == "a smooth grey rock"
    assert thing.portable is True
    assert thing.aliases == ["stone"]
    assert thing.location is test_zone
    assert thing.x == 3
    assert thing.y == 7
    assert thing in test_zone.contents


def test_spawn_thing_without_coordinates(test_zone):
    """spawn_thing can create a thing without position (template/inventory)."""
    template = ThingTemplate(name="gem", description="a sparkling gem")
    thing = spawn_thing(template, None)
    assert thing.location is None
    assert thing.x is None
    assert thing.y is None
