"""Tests for mob home region system."""

import pathlib
import tempfile

import pytest

from mudlib.entity import Mob
from mudlib.mobs import MobTemplate, mobs, spawn_mob
from mudlib.zone import SpawnRule, Zone
from mudlib.zones import load_zone


@pytest.fixture(autouse=True)
def clear_mobs():
    mobs.clear()
    yield
    mobs.clear()


@pytest.fixture
def zone():
    terrain = [["." for _ in range(20)] for _ in range(20)]
    return Zone(
        name="forest",
        width=20,
        height=20,
        terrain=terrain,
        toroidal=False,
    )


@pytest.fixture
def template():
    return MobTemplate(
        name="squirrel",
        description="a bushy-tailed squirrel",
        pl=10,
        stamina=20,
        max_stamina=20,
        moves=[],
    )


# --- SpawnRule ---


def test_spawn_rule_default_no_home_region():
    """SpawnRule has no home_region by default."""
    rule = SpawnRule(mob="goblin")
    assert rule.home_region is None


def test_spawn_rule_with_home_region():
    """SpawnRule can have a home_region."""
    rule = SpawnRule(
        mob="goblin",
        home_region={"x": [5, 15], "y": [3, 10]},
    )
    assert rule.home_region == {"x": [5, 15], "y": [3, 10]}


# --- Mob fields ---


def test_mob_home_region_defaults():
    """Mob has no home region by default."""
    mob = Mob(name="rat", x=0, y=0)
    assert mob.home_x_min is None
    assert mob.home_x_max is None
    assert mob.home_y_min is None
    assert mob.home_y_max is None


def test_mob_home_region_set():
    """Mob can have home region bounds."""
    mob = Mob(
        name="rat",
        x=5,
        y=5,
        home_x_min=3,
        home_x_max=10,
        home_y_min=2,
        home_y_max=8,
    )
    assert mob.home_x_min == 3
    assert mob.home_x_max == 10
    assert mob.home_y_min == 2
    assert mob.home_y_max == 8


def test_mob_in_home_region():
    """Mob at position within home region."""
    mob = Mob(
        name="rat",
        x=5,
        y=5,
        home_x_min=3,
        home_x_max=10,
        home_y_min=2,
        home_y_max=8,
    )
    assert mob.home_x_min is not None
    assert mob.home_x_max is not None
    assert mob.home_y_min is not None
    assert mob.home_y_max is not None
    assert mob.home_x_min <= mob.x <= mob.home_x_max
    assert mob.home_y_min <= mob.y <= mob.home_y_max


# --- spawn_mob with home region ---


def test_spawn_mob_with_home_region(zone, template):
    """spawn_mob sets home region from SpawnRule."""
    rule = SpawnRule(
        mob="squirrel",
        home_region={"x": [5, 15], "y": [3, 10]},
    )
    mob = spawn_mob(template, 10, 7, zone, home_region=rule.home_region)
    assert mob.home_x_min == 5
    assert mob.home_x_max == 15
    assert mob.home_y_min == 3
    assert mob.home_y_max == 10


def test_spawn_mob_without_home_region(zone, template):
    """spawn_mob without home_region leaves bounds as None."""
    mob = spawn_mob(template, 10, 7, zone)
    assert mob.home_x_min is None
    assert mob.home_x_max is None


# --- TOML loading ---


def test_load_zone_spawn_with_home_region():
    """Zone TOML with home_region on spawn rule."""
    with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f:
        f.write(
            """
name = "test_zone"
width = 20
height = 20

[terrain]
rows = [
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
]

[[spawns]]
mob = "squirrel"
max_count = 2
respawn_seconds = 180
home_region = { x = [5, 15], y = [3, 10] }
"""
        )
        temp_path = pathlib.Path(f.name)

    try:
        zone = load_zone(temp_path)
        assert len(zone.spawn_rules) == 1
        rule = zone.spawn_rules[0]
        assert rule.home_region == {"x": [5, 15], "y": [3, 10]}
    finally:
        temp_path.unlink()


def test_load_zone_spawn_without_home_region():
    """Zone TOML without home_region on spawn rule."""
    with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f:
        f.write(
            """
name = "test_zone"
width = 5
height = 5

[terrain]
rows = [
    ".....",
    ".....",
    ".....",
    ".....",
    ".....",
]

[[spawns]]
mob = "goblin"
max_count = 1
"""
        )
        temp_path = pathlib.Path(f.name)

    try:
        zone = load_zone(temp_path)
        assert len(zone.spawn_rules) == 1
        rule = zone.spawn_rules[0]
        assert rule.home_region is None
    finally:
        temp_path.unlink()
