# Navigation operations module
# Handles: add_navigation_region, set_navigation_navmesh, add_navigation_obstacle, add_navigation_agent
# Corresponds to: test_navigation.py
class_name NavigationOps


## Add a navigation region to a scene
static func add_navigation_region(ctx: SceneTree, params: Dictionary) -> void:
	ctx.log_info("Adding navigation region: " + params.region_name)

	var full_scene_path: String = params.scene_path
	if not full_scene_path.begins_with("res://"):
		full_scene_path = "res://" + full_scene_path

	if not FileAccess.file_exists(full_scene_path):
		ctx.log_error("Scene file does not exist: " + full_scene_path)
		ctx.quit(1)

	var scene: PackedScene = load(full_scene_path)
	if not scene:
		ctx.log_error("Failed to load scene: " + full_scene_path)
		ctx.quit(1)

	var scene_root: Node = scene.instantiate()

	# Find parent node
	var parent_node: Node = scene_root.get_node_or_null(NodePath(params.parent_node_path))
	if not parent_node:
		ctx.log_error("Parent node not found: " + params.parent_node_path)
		ctx.quit(1)

	# Create navigation region
	var region: Node = ctx.instantiate_class(params.region_type)
	if not region:
		ctx.log_error("Failed to create navigation region of type: " + params.region_type)
		ctx.quit(1)

	region.name = params.region_name

	# Create a basic navigation mesh/polygon based on type
	if params.region_type == "NavigationRegion2D":
		var nav_poly: NavigationPolygon = NavigationPolygon.new()
		# Create a simple square polygon
		var outline: PackedVector2Array = PackedVector2Array([
			Vector2(-100, -100),
			Vector2(100, -100),
			Vector2(100, 100),
			Vector2(-100, 100)
		])
		nav_poly.add_outline(outline)
		nav_poly.make_polygons_from_outlines()
		region.navigation_polygon = nav_poly
		if ctx.debug_mode:
			print("[DEBUG] Created NavigationPolygon for 2D region")
	elif params.region_type == "NavigationRegion3D":
		var nav_mesh: NavigationMesh = NavigationMesh.new()
		region.navigation_mesh = nav_mesh
		if ctx.debug_mode:
			print("[DEBUG] Created NavigationMesh for 3D region")

	# Add to scene
	parent_node.add_child(region)
	region.owner = scene_root

	if ctx.debug_mode:
		print("[DEBUG] Navigation region added to scene")

	# Save scene
	var packed_scene: PackedScene = PackedScene.new()
	var result: int = packed_scene.pack(scene_root)

	if result == OK:
		var save_error: int = ResourceSaver.save(packed_scene, full_scene_path)
		if save_error == OK:
			print("Navigation region '" + params.region_name + "' added successfully")
		else:
			ctx.log_error("Failed to save scene: " + str(save_error))
			ctx.quit(1)
	else:
		ctx.log_error("Failed to pack scene: " + str(result))
		ctx.quit(1)


## Set or bake navigation mesh for a region
static func set_navigation_navmesh(ctx: SceneTree, params: Dictionary) -> void:
	ctx.log_info("Setting navigation mesh")

	var full_scene_path: String = params.scene_path
	if not full_scene_path.begins_with("res://"):
		full_scene_path = "res://" + full_scene_path

	if not FileAccess.file_exists(full_scene_path):
		ctx.log_error("Scene file does not exist: " + full_scene_path)
		ctx.quit(1)

	var scene: PackedScene = load(full_scene_path)
	if not scene:
		ctx.log_error("Failed to load scene: " + full_scene_path)
		ctx.quit(1)

	var scene_root: Node = scene.instantiate()

	# Find navigation region
	var region: Node = scene_root.get_node_or_null(NodePath(params.region_path))
	if not region:
		ctx.log_error("Navigation region not found: " + params.region_path)
		ctx.quit(1)

	# Handle different region types
	if region is NavigationRegion2D:
		if params.has("navmesh_path"):
			var navmesh_full_path: String = params.navmesh_path
			if not navmesh_full_path.begins_with("res://"):
				navmesh_full_path = "res://" + navmesh_full_path
			var nav_poly: NavigationPolygon = load(navmesh_full_path)
			if nav_poly:
				region.navigation_polygon = nav_poly
				if ctx.debug_mode:
					print("[DEBUG] Loaded NavigationPolygon from: " + navmesh_full_path)
			else:
				ctx.log_error("Failed to load NavigationPolygon from: " + navmesh_full_path)
				ctx.quit(1)
		elif params.get("bake", false):
			# For 2D, we need to have geometry to bake from
			# This is a simplified implementation
			if region.navigation_polygon == null:
				region.navigation_polygon = NavigationPolygon.new()
			if ctx.debug_mode:
				print("[DEBUG] Baking navigation mesh for 2D region (simplified)")
	elif region is NavigationRegion3D:
		if params.has("navmesh_path"):
			var navmesh_full_path: String = params.navmesh_path
			if not navmesh_full_path.begins_with("res://"):
				navmesh_full_path = "res://" + navmesh_full_path
			var nav_mesh: NavigationMesh = load(navmesh_full_path)
			if nav_mesh:
				region.navigation_mesh = nav_mesh
				if ctx.debug_mode:
					print("[DEBUG] Loaded NavigationMesh from: " + navmesh_full_path)
			else:
				ctx.log_error("Failed to load NavigationMesh from: " + navmesh_full_path)
				ctx.quit(1)
		elif params.get("bake", false):
			if region.navigation_mesh == null:
				region.navigation_mesh = NavigationMesh.new()
			# Note: Actual baking requires NavigationServer and geometry in the scene
			if ctx.debug_mode:
				print("[DEBUG] Baking navigation mesh for 3D region (simplified)")
	else:
		ctx.log_error("Node is not a navigation region: " + params.region_path)
		ctx.quit(1)

	if ctx.debug_mode:
		print("[DEBUG] Navigation mesh set")

	# Save scene
	var packed_scene: PackedScene = PackedScene.new()
	var result: int = packed_scene.pack(scene_root)

	if result == OK:
		var save_error: int = ResourceSaver.save(packed_scene, full_scene_path)
		if save_error == OK:
			print("Navigation mesh set successfully")
		else:
			ctx.log_error("Failed to save scene: " + str(save_error))
			ctx.quit(1)
	else:
		ctx.log_error("Failed to pack scene: " + str(result))
		ctx.quit(1)


## Add a navigation obstacle
static func add_navigation_obstacle(ctx: SceneTree, params: Dictionary) -> void:
	ctx.log_info("Adding navigation obstacle: " + params.obstacle_name)

	var full_scene_path: String = params.scene_path
	if not full_scene_path.begins_with("res://"):
		full_scene_path = "res://" + full_scene_path

	if not FileAccess.file_exists(full_scene_path):
		ctx.log_error("Scene file does not exist: " + full_scene_path)
		ctx.quit(1)

	var scene: PackedScene = load(full_scene_path)
	if not scene:
		ctx.log_error("Failed to load scene: " + full_scene_path)
		ctx.quit(1)

	var scene_root: Node = scene.instantiate()

	# Find parent node
	var parent_node: Node = scene_root.get_node_or_null(NodePath(params.parent_node_path))
	if not parent_node:
		ctx.log_error("Parent node not found: " + params.parent_node_path)
		ctx.quit(1)

	# Create obstacle
	var obstacle: Node = ctx.instantiate_class(params.obstacle_type)
	if not obstacle:
		ctx.log_error("Failed to create obstacle of type: " + params.obstacle_type)
		ctx.quit(1)

	obstacle.name = params.obstacle_name

	# Set radius
	if params.has("radius"):
		obstacle.radius = params.radius

	# Add to scene
	parent_node.add_child(obstacle)
	obstacle.owner = scene_root

	if ctx.debug_mode:
		print("[DEBUG] Navigation obstacle added to scene")

	# Save scene
	var packed_scene: PackedScene = PackedScene.new()
	var result: int = packed_scene.pack(scene_root)

	if result == OK:
		var save_error: int = ResourceSaver.save(packed_scene, full_scene_path)
		if save_error == OK:
			print("Navigation obstacle '" + params.obstacle_name + "' added successfully")
		else:
			ctx.log_error("Failed to save scene: " + str(save_error))
			ctx.quit(1)
	else:
		ctx.log_error("Failed to pack scene: " + str(result))
		ctx.quit(1)


## Add a navigation agent
static func add_navigation_agent(ctx: SceneTree, params: Dictionary) -> void:
	ctx.log_info("Adding navigation agent: " + params.agent_name)

	var full_scene_path: String = params.scene_path
	if not full_scene_path.begins_with("res://"):
		full_scene_path = "res://" + full_scene_path

	if not FileAccess.file_exists(full_scene_path):
		ctx.log_error("Scene file does not exist: " + full_scene_path)
		ctx.quit(1)

	var scene: PackedScene = load(full_scene_path)
	if not scene:
		ctx.log_error("Failed to load scene: " + full_scene_path)
		ctx.quit(1)

	var scene_root: Node = scene.instantiate()

	# Find parent node
	var parent_node: Node = scene_root.get_node_or_null(NodePath(params.parent_node_path))
	if not parent_node:
		ctx.log_error("Parent node not found: " + params.parent_node_path)
		ctx.quit(1)

	# Create agent
	var agent: Node = ctx.instantiate_class(params.agent_type)
	if not agent:
		ctx.log_error("Failed to create agent of type: " + params.agent_type)
		ctx.quit(1)

	agent.name = params.agent_name

	# Set properties
	if params.has("max_speed"):
		agent.max_speed = params.max_speed
	if params.has("radius"):
		agent.radius = params.radius

	# Add to scene
	parent_node.add_child(agent)
	agent.owner = scene_root

	if ctx.debug_mode:
		print("[DEBUG] Navigation agent added to scene")

	# Save scene
	var packed_scene: PackedScene = PackedScene.new()
	var result: int = packed_scene.pack(scene_root)

	if result == OK:
		var save_error: int = ResourceSaver.save(packed_scene, full_scene_path)
		if save_error == OK:
			print("Navigation agent '" + params.agent_name + "' added successfully")
		else:
			ctx.log_error("Failed to save scene: " + str(save_error))
			ctx.quit(1)
	else:
		ctx.log_error("Failed to pack scene: " + str(result))
		ctx.quit(1)
