"""Tests for navigation operations."""

from pathlib import Path

import pytest

from godot_mcp.server import (
    navigation_add_region,
    navigation_set_navmesh,
    navigation_add_obstacle,
    navigation_add_agent,
    scene_create,
)


class TestNavigationAddRegion:
    """Test cases for navigation_add_region tool."""

    def test_add_navigation_region_2d(self, temp_godot_project: Path) -> None:
        """Test adding a NavigationRegion2D."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            root_node_type="Node2D",
        )

        result = navigation_add_region(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            region_name="NavigationRegion",
            region_type="NavigationRegion2D",
        )

        assert "successfully" in result.lower() or "added" in result.lower()
        assert "NavigationRegion" in result

    def test_add_navigation_region_3d(self, temp_godot_project: Path) -> None:
        """Test adding a NavigationRegion3D."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            root_node_type="Node3D",
        )

        result = navigation_add_region(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            region_name="NavRegion3D",
            region_type="NavigationRegion3D",
        )

        assert "successfully" in result.lower() or "added" in result.lower()

    def test_navigation_region_invalid_type(self, temp_godot_project: Path) -> None:
        """Test error handling for invalid region type."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
        )

        result = navigation_add_region(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            region_name="Invalid",
            region_type="InvalidRegion",
        )

        assert "Invalid region type" in result


class TestNavigationSetNavmesh:
    """Test cases for navigation_set_navmesh tool."""

    def test_set_navmesh_bake(self, temp_godot_project: Path) -> None:
        """Test baking a navigation mesh."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            root_node_type="Node2D",
        )

        # Add region first
        navigation_add_region(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            region_name="NavRegion",
            region_type="NavigationRegion2D",
        )

        # Set navmesh
        result = navigation_set_navmesh(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            region_path="NavRegion",
            bake=True,
        )

        assert "successfully" in result.lower() or "set" in result.lower()


class TestNavigationAddObstacle:
    """Test cases for navigation_add_obstacle tool."""

    def test_add_obstacle_2d(self, temp_godot_project: Path) -> None:
        """Test adding a NavigationObstacle2D."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            root_node_type="Node2D",
        )

        result = navigation_add_obstacle(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            obstacle_name="Obstacle",
            obstacle_type="NavigationObstacle2D",
            radius=15.0,
        )

        assert "successfully" in result.lower() or "added" in result.lower()
        assert "Obstacle" in result

    def test_add_obstacle_3d(self, temp_godot_project: Path) -> None:
        """Test adding a NavigationObstacle3D."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            root_node_type="Node3D",
        )

        result = navigation_add_obstacle(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            obstacle_name="Obstacle3D",
            obstacle_type="NavigationObstacle3D",
        )

        assert "successfully" in result.lower() or "added" in result.lower()


class TestNavigationAddAgent:
    """Test cases for navigation_add_agent tool."""

    def test_add_agent_2d(self, temp_godot_project: Path) -> None:
        """Test adding a NavigationAgent2D."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            root_node_type="Node2D",
        )

        result = navigation_add_agent(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            agent_name="Agent",
            agent_type="NavigationAgent2D",
            max_speed=300.0,
            radius=12.0,
        )

        assert "successfully" in result.lower() or "added" in result.lower()
        assert "Agent" in result

    def test_add_agent_3d(self, temp_godot_project: Path) -> None:
        """Test adding a NavigationAgent3D."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            root_node_type="Node3D",
        )

        result = navigation_add_agent(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            agent_name="Agent3D",
            agent_type="NavigationAgent3D",
        )

        assert "successfully" in result.lower() or "added" in result.lower()

    def test_add_agent_invalid_type(self, temp_godot_project: Path) -> None:
        """Test error handling for invalid agent type."""
        scene_path = "test_scene.tscn"
        scene_create(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
        )

        result = navigation_add_agent(
            project_path=str(temp_godot_project),
            scene_path=scene_path,
            parent_node_path=".",
            agent_name="Invalid",
            agent_type="InvalidAgent",
        )

        assert "Invalid agent type" in result
