## SimulationServerStub — lightweight GDScript replacement for GDExtension C++ core.
##
## Provides the same API surface so game_server.gd and FPSCharacterController
## work without the compiled GDExtension library. No 128Hz simulation — just
## stores entity state and passes through input. Replace with the C++
## SimulationServer once `scons` builds cleanly.
extends RefCounted

# ---------------------------------------------------------------------------
# Nested: Entity state data
# ---------------------------------------------------------------------------
class Entity:
	var id: int = -1
	var peer_id: int = -1
	var position: Vector3 = Vector3.ZERO
	var rotation: Vector3 = Vector3.ZERO
	var velocity: Vector3 = Vector3.ZERO
	var alive: bool = true
	var health: float = 100.0
	var input_sequence: int = 0

	func is_alive() -> bool:
		return alive

# ---------------------------------------------------------------------------
# Config
# ---------------------------------------------------------------------------
var _tick_rate: int = 128
var _movement_config: Dictionary = {}
var _weapon_config: Dictionary = {}
var _history_depth: int = 64
var _next_entity_id: int = 1
var _entities: Dictionary = {}  # entity_id → Entity

# ---------------------------------------------------------------------------
# SimulationServer API
# ---------------------------------------------------------------------------
func set_tick_rate(hz: int) -> void:
	_tick_rate = hz

func get_tick_rate() -> int:
	return _tick_rate

func set_movement_config(cfg: Dictionary) -> void:
	_movement_config = cfg

func set_weapon_config(cfg: Dictionary) -> void:
	_weapon_config = cfg

func set_history_depth(depth: int) -> void:
	_history_depth = depth

func apply_input(entity_id: int, input_dict: Dictionary) -> void:
	var e: Entity = _entities.get(entity_id)
	if e == null:
		return
	# Apply movement from input (simplified)
	if input_dict.has("move_direction"):
		var dir: Vector3 = input_dict["move_direction"]
		var speed: float = 5.0
		if input_dict.get("sprint", false):
			speed = 8.0
		elif input_dict.get("crouch", false):
			speed = 2.5
		e.velocity = dir * speed
		e.position += e.velocity * (1.0 / _tick_rate)
	# Track input sequence
	if input_dict.has("input_sequence"):
		e.input_sequence = input_dict["input_sequence"]

func fire_weapon(entity_id: int) -> void:
	# Stub: log the event
	pass

func get_entity(entity_id: int) -> Entity:
	return _entities.get(entity_id)

func spawn_player_entity(peer_id: int, pos: Vector3) -> int:
	var e = Entity.new()
	e.id = _next_entity_id
	e.peer_id = peer_id
	e.position = pos
	e.alive = true
	e.health = 100.0
	_entities[_next_entity_id] = e
	_next_entity_id += 1
	return e.id

func despawn_player_entity(entity_id: int) -> void:
	_entities.erase(entity_id)

func tick(delta: float) -> void:
	# Stub: in the real C++ SimulationServer this runs the 128Hz simulation
	pass

func get_entity_count() -> int:
	return _entities.size()
