"""Tests for YAML map import script."""

from __future__ import annotations

from pathlib import Path

import pytest

from mudlib.portal import Portal
from mudlib.zones import load_zone


def test_minimal_yaml_import(tmp_path: Path) -> None:
    """Test importing a minimal YAML map."""
    yaml_content = """
name: test_zone
width: 5
height: 5
terrain:
  rows:
    - "....."
    - "....."
    - "....."
    - "....."
    - "....."
"""
    yaml_file = tmp_path / "test_zone.yaml"
    yaml_file.write_text(yaml_content)

    # Import the script module
    from scripts.import_map import import_map

    output_file = import_map(yaml_file, tmp_path)

    # Verify TOML was created
    assert output_file.exists()
    assert output_file.name == "test_zone.toml"

    # Verify it can be loaded by existing zone loader
    zone = load_zone(output_file)
    assert zone.name == "test_zone"
    assert zone.width == 5
    assert zone.height == 5
    assert zone.description == ""
    assert zone.toroidal is True  # default
    assert zone.spawn_x == 0  # default
    assert zone.spawn_y == 0  # default
    assert zone.safe is False  # default
    assert len(zone.terrain) == 5
    assert all(len(row) == 5 for row in zone.terrain)


def test_full_featured_yaml_import(tmp_path: Path) -> None:
    """Test importing a YAML map with all features."""
    yaml_content = """
name: complex_zone
description: a complex test zone
width: 10
height: 10
toroidal: false
spawn: [5, 5]
safe: true

terrain:
  rows:
    - "##########"
    - "#........#"
    - "#........#"
    - "#........#"
    - "#........#"
    - "#........#"
    - "#........#"
    - "#........#"
    - "#........#"
    - "##########"
  impassable: ["#"]

ambient:
  interval: 60
  messages:
    - "wind howls..."
    - "a distant sound"

portals:
  - x: 5
    y: 0
    target: "other_zone:10,10"
    label: "a wide path"
    aliases: ["path", "wide"]

spawns:
  - mob: goblin
    max_count: 3
    respawn_seconds: 300
    home_region:
      x: [1, 9]
      y: [1, 9]
"""
    yaml_file = tmp_path / "complex_zone.yaml"
    yaml_file.write_text(yaml_content)

    from scripts.import_map import import_map

    output_file = import_map(yaml_file, tmp_path)

    # Load and verify all fields
    zone = load_zone(output_file)
    assert zone.name == "complex_zone"
    assert zone.description == "a complex test zone"
    assert zone.width == 10
    assert zone.height == 10
    assert zone.toroidal is False
    assert zone.spawn_x == 5
    assert zone.spawn_y == 5
    assert zone.safe is True

    # Verify terrain
    assert len(zone.terrain) == 10
    assert zone.terrain[0] == list("##########")
    assert zone.terrain[1] == list("#........#")

    # Verify impassable
    assert "#" in zone.impassable

    # Verify ambient messages
    assert zone.ambient_messages == ["wind howls...", "a distant sound"]
    assert zone.ambient_interval == 60

    # Verify portals
    portals = [obj for obj in zone._contents if isinstance(obj, Portal)]
    assert len(portals) == 1
    portal = portals[0]
    assert portal.x == 5
    assert portal.y == 0
    assert portal.target_zone == "other_zone"
    assert portal.target_x == 10
    assert portal.target_y == 10
    assert portal.name == "a wide path"
    assert portal.aliases == ["path", "wide"]

    # Verify spawn rules
    assert len(zone.spawn_rules) == 1
    spawn = zone.spawn_rules[0]
    assert spawn.mob == "goblin"
    assert spawn.max_count == 3
    assert spawn.respawn_seconds == 300
    assert spawn.home_region == {"x": [1, 9], "y": [1, 9]}


def test_missing_required_field_raises_error(tmp_path: Path) -> None:
    """Test that missing required fields raise appropriate errors."""
    yaml_content = """
width: 5
height: 5
"""
    yaml_file = tmp_path / "incomplete.yaml"
    yaml_file.write_text(yaml_content)

    from scripts.import_map import import_map

    with pytest.raises(KeyError, match="name"):
        import_map(yaml_file, tmp_path)


def test_spawn_list_format(tmp_path: Path) -> None:
    """Test that spawn coordinates as [x, y] list are parsed correctly."""
    yaml_content = """
name: spawn_test
width: 3
height: 3
spawn: [1, 2]
terrain:
  rows:
    - "..."
    - "..."
    - "..."
"""
    yaml_file = tmp_path / "spawn_test.yaml"
    yaml_file.write_text(yaml_content)

    from scripts.import_map import import_map

    output_file = import_map(yaml_file, tmp_path)
    zone = load_zone(output_file)
    assert zone.spawn_x == 1
    assert zone.spawn_y == 2


def test_defaults_applied(tmp_path: Path) -> None:
    """Test that sensible defaults are applied for optional fields."""
    yaml_content = """
name: defaults_test
width: 3
height: 3
terrain:
  rows:
    - "..."
    - "..."
    - "..."
"""
    yaml_file = tmp_path / "defaults_test.yaml"
    yaml_file.write_text(yaml_content)

    from scripts.import_map import import_map

    output_file = import_map(yaml_file, tmp_path)
    zone = load_zone(output_file)

    # Verify defaults
    assert zone.toroidal is True
    assert zone.spawn_x == 0
    assert zone.spawn_y == 0
    assert zone.safe is False
    assert zone.ambient_messages == []
    assert zone.spawn_rules == []


def test_multiple_portals(tmp_path: Path) -> None:
    """Test importing multiple portals."""
    yaml_content = """
name: multi_portal
width: 5
height: 5
terrain:
  rows:
    - "....."
    - "....."
    - "....."
    - "....."
    - "....."
portals:
  - x: 0
    y: 0
    target: "zone1:5,5"
    label: "north path"
  - x: 4
    y: 4
    target: "zone2:0,0"
    label: "south path"
"""
    yaml_file = tmp_path / "multi_portal.yaml"
    yaml_file.write_text(yaml_content)

    from scripts.import_map import import_map

    output_file = import_map(yaml_file, tmp_path)
    zone = load_zone(output_file)

    portals = [obj for obj in zone._contents if isinstance(obj, Portal)]
    assert len(portals) == 2


def test_multiple_spawns(tmp_path: Path) -> None:
    """Test importing multiple spawn rules."""
    yaml_content = """
name: multi_spawn
width: 5
height: 5
terrain:
  rows:
    - "....."
    - "....."
    - "....."
    - "....."
    - "....."
spawns:
  - mob: goblin
    max_count: 2
  - mob: orc
    max_count: 1
    respawn_seconds: 600
"""
    yaml_file = tmp_path / "multi_spawn.yaml"
    yaml_file.write_text(yaml_content)

    from scripts.import_map import import_map

    output_file = import_map(yaml_file, tmp_path)
    zone = load_zone(output_file)

    assert len(zone.spawn_rules) == 2
    assert zone.spawn_rules[0].mob == "goblin"
    assert zone.spawn_rules[0].max_count == 2
    assert zone.spawn_rules[1].mob == "orc"
    assert zone.spawn_rules[1].respawn_seconds == 600
