## PathfindingHandler.gd
# Handles A* pathfinding for the map using Godot's AStar2D.
# Builds a navigation graph from walkable tiles and provides path queries.
class_name PathfindingHandler
extends RefCounted

# All 8 possible neighbor offsets (cardinal and diagonal directions).
const NEIGHBORS: Array[Vector2i] = [
	Vector2i.RIGHT, Vector2i.LEFT, Vector2i.DOWN, Vector2i.UP,
	Vector2i(1, 1), Vector2i(1, -1), Vector2i(-1, 1), Vector2i(-1, -1),
]

# The underlying AStar2D instance for pathfinding.
var _astar: AStar2D = AStar2D.new()
# Maps grid coordinates (Vector2i) to AStar2D point IDs.
var _coord_to_id: Dictionary = {}

# Builds the AStar2D graph from all walkable tiles in MapData.
# Safe to call again for a new level — clears all previous state first.
func build(data: MapData) -> void:
	_astar.clear()
	_coord_to_id.clear()

	# Register a point for every walkable tile (FLOOR).
	for coords: Vector2i in data.grid.keys():
		if data.grid[coords] == MapData.TileType.FLOOR:
			var id: int = _astar.get_available_point_id()
			_astar.add_point(id, Vector2(coords.x, coords.y))
			_coord_to_id[coords] = id

	# Connect each point to its walkable neighbors (cardinal and diagonal).
	for coords: Vector2i in _coord_to_id.keys():
		for offset: Vector2i in NEIGHBORS:
			var neighbor: Vector2i = coords + offset
			if _coord_to_id.has(neighbor):
				_astar.connect_points(_coord_to_id[coords], _coord_to_id[neighbor], false)

# Returns the path as grid coordinates, or an empty array if no path exists.
# Used by LevelManager and Player for navigation.
func find_path(from: Vector2i, to: Vector2i) -> Array[Vector2i]:
	if not _coord_to_id.has(from) or not _coord_to_id.has(to):
		return []

	var raw: PackedVector2Array = _astar.get_point_path(_coord_to_id[from], _coord_to_id[to])
	var result: Array[Vector2i] = []
	for point in raw:
		result.append(Vector2i(point))
	return result
