"""
Integration tests for TileMap operations.

Tests the TileMap manipulation features:
- tilemap_set_cell: Place tiles in TileMap nodes
- tilemap_get_cell: Read tiles from TileMap nodes
"""

import json
from pathlib import Path

import pytest

from godot_mcp.server import (
    GodotServer,
    node_add,
    scene_create,
    tilemap_get_cell,
    tilemap_set_cell,
)


class TestSetTilemapCell:
    """Tests for the tilemap_set_cell tool."""

    @pytest.fixture
    def temp_tilemap_scene(self, temp_godot_project: Path) -> Path:
        """Create a temporary scene with a TileMap node."""
        # First create a basic scene with Node2D root
        scene_create(
            project_path=str(temp_godot_project),
            scene_path="tilemap_test.tscn",
            root_node_type="Node2D",
        )

        # Add a TileMap node to the scene
        node_add(
            project_path=str(temp_godot_project),
            scene_path="tilemap_test.tscn",
            node_type="TileMap",
            node_name="TileMap",
            parent_node_path="root",
        )

        return Path("tilemap_test.tscn")

    def test_tilemap_set_cell_basic(
        self,
        temp_godot_project: Path,
        temp_tilemap_scene: Path,
        godot_client: GodotServer,
    ) -> None:
        """Test setting a basic tilemap cell."""
        result = tilemap_set_cell(
            project_path=str(temp_godot_project),
            scene_path=str(temp_tilemap_scene),
            node_path="root/TileMap",
            x=0,
            y=0,
            source_id=0,
            atlas_x=0,
            atlas_y=0,
        )

        # The operation should complete (may warn about missing tileset)
        assert "tilemap" in result.lower() or "cell" in result.lower()

    def test_tilemap_set_cell_multiple(
        self,
        temp_godot_project: Path,
        temp_tilemap_scene: Path,
        godot_client: GodotServer,
    ) -> None:
        """Test setting multiple tilemap cells."""
        # Set a row of cells
        for x in range(5):
            result = tilemap_set_cell(
                project_path=str(temp_godot_project),
                scene_path=str(temp_tilemap_scene),
                node_path="root/TileMap",
                x=x,
                y=0,
                source_id=0,
            )
            # Should not fail
            assert "error" not in result.lower() or "tilemap" in result.lower()

    def test_tilemap_set_cell_invalid_scene(self, temp_godot_project: Path) -> None:
        """Test that invalid scene paths are rejected."""
        result = tilemap_set_cell(
            project_path=str(temp_godot_project),
            scene_path="nonexistent.tscn",
            node_path="root/TileMap",
            x=0,
            y=0,
        )

        assert "error" in result.lower() or "not exist" in result.lower()


class TestGetTilemapCell:
    """Tests for the tilemap_get_cell tool (Read operation)."""

    @pytest.fixture
    def temp_tilemap_scene(self, temp_godot_project: Path) -> Path:
        """Create a temporary scene with a TileMap node."""
        scene_create(
            project_path=str(temp_godot_project),
            scene_path="tilemap_read_test.tscn",
            root_node_type="Node2D",
        )
        node_add(
            project_path=str(temp_godot_project),
            scene_path="tilemap_read_test.tscn",
            node_type="TileMap",
            node_name="TileMap",
            parent_node_path="root",
        )
        return Path("tilemap_read_test.tscn")

    def test_tilemap_get_cell_empty(
        self,
        temp_godot_project: Path,
        temp_tilemap_scene: Path,
        godot_client: GodotServer,
    ) -> None:
        """Test getting an empty tilemap cell."""
        result = tilemap_get_cell(
            project_path=str(temp_godot_project),
            scene_path=str(temp_tilemap_scene),
            node_path="root/TileMap",
            x=0,
            y=0,
        )

        # Should return valid JSON
        data = json.loads(result)
        assert "x" in data
        assert "y" in data
        assert "is_empty" in data
        # Empty cell should have source_id of -1
        assert data["source_id"] == -1 or data["is_empty"] is True

    def test_tilemap_get_cell_after_set(
        self,
        temp_godot_project: Path,
        temp_tilemap_scene: Path,
        godot_client: GodotServer,
    ) -> None:
        """Test getting a tilemap cell after setting it."""
        # First set a cell
        tilemap_set_cell(
            project_path=str(temp_godot_project),
            scene_path=str(temp_tilemap_scene),
            node_path="root/TileMap",
            x=5,
            y=3,
            source_id=0,
            atlas_x=1,
            atlas_y=2,
        )

        # Now read it back
        result = tilemap_get_cell(
            project_path=str(temp_godot_project),
            scene_path=str(temp_tilemap_scene),
            node_path="root/TileMap",
            x=5,
            y=3,
        )

        data = json.loads(result)
        assert data["x"] == 5
        assert data["y"] == 3
        # Note: Without a TileSet configured, the cell might still be empty
        # but the coordinates should match

    def test_tilemap_get_cell_invalid_scene(self, temp_godot_project: Path) -> None:
        """Test that invalid scene paths are rejected."""
        result = tilemap_get_cell(
            project_path=str(temp_godot_project),
            scene_path="nonexistent.tscn",
            node_path="root/TileMap",
            x=0,
            y=0,
        )
        assert "error" in result.lower() or "not exist" in result.lower()
