## SpatialGrid — 2D 空间哈希网格 Autoload（GDScript 外壳）
## 热路径由 C# SpatialGridCs 子节点执行（就绪后接管）
## 权威来源：architecture_design.md §4.3
extends Node

const CELL_SIZE:   int = 64    # 格子大小（像素）
const GRID_COLS:   int = 128   # 128×128 格 × 64px = 8192×8192 覆盖范围
const GRID_ROWS:   int = 128
const GRID_OFFSET: int = 4096  # 将世界中心映射到网格中心（支持负坐标）

var _cs_node: Node = null      # SpatialGridCs C# 子节点（就绪后挂载）

## GDScript 回退网格
var _grid:        Array      = []  # Array[Array[int]]
var _entity_cell: Dictionary = {}  # { entity_id → cell_idx }

func _ready() -> void:
	_grid.resize(GRID_COLS * GRID_ROWS)
	for i in _grid.size():
		_grid[i] = []

## 插入或更新实体位置（由 EnemyManager 每物理帧调用）
func insert(entity_id: int, pos: Vector2) -> void:
	if _cs_node and _cs_node.has_method("Insert"):
		_cs_node.call("Insert", entity_id, pos)
		return
	var cx: int = clamp(int((pos.x + GRID_OFFSET) / CELL_SIZE), 0, GRID_COLS - 1)
	var cy: int = clamp(int((pos.y + GRID_OFFSET) / CELL_SIZE), 0, GRID_ROWS - 1)
	var cell: int = cx + cy * GRID_COLS
	var old_cell: int = _entity_cell.get(entity_id, -1)
	if old_cell == cell:
		return
	if old_cell >= 0:
		_grid[old_cell].erase(entity_id)
	_grid[cell].append(entity_id)
	_entity_cell[entity_id] = cell

## 查询圆形范围内的所有实体 ID
func query_circle(center: Vector2, radius: float) -> PackedInt32Array:
	if _cs_node and _cs_node.has_method("QueryCircle"):
		return _cs_node.call("QueryCircle", center, radius)
	var result := PackedInt32Array()
	var min_cx: int = clamp(int((center.x - radius + GRID_OFFSET) / CELL_SIZE), 0, GRID_COLS - 1)
	var max_cx: int = clamp(int((center.x + radius + GRID_OFFSET) / CELL_SIZE), 0, GRID_COLS - 1)
	var min_cy: int = clamp(int((center.y - radius + GRID_OFFSET) / CELL_SIZE), 0, GRID_ROWS - 1)
	var max_cy: int = clamp(int((center.y + radius + GRID_OFFSET) / CELL_SIZE), 0, GRID_ROWS - 1)
	for cy in range(min_cy, max_cy + 1):
		for cx in range(min_cx, max_cx + 1):
			for eid in _grid[cx + cy * GRID_COLS]:
				result.append(eid)
	return result

## 每帧由 EnemyManager._physics_process 驱动（dirty-list 方案）
func rebuild() -> void:
	if _cs_node and _cs_node.has_method("Rebuild"):
		_cs_node.call("Rebuild")

## 移除实体
func remove_entity(entity_id: int) -> void:
	if _cs_node and _cs_node.has_method("Remove"):
		_cs_node.call("Remove", entity_id)
		return
	var old_cell: int = _entity_cell.get(entity_id, -1)
	if old_cell >= 0:
		_grid[old_cell].erase(entity_id)
		_entity_cell.erase(entity_id)

## 清空（关卡重置）
func clear() -> void:
	if _cs_node and _cs_node.has_method("Clear"):
		_cs_node.call("Clear")
		return
	for cell_list in _grid:
		(cell_list as Array).clear()
	_entity_cell.clear()
