extends Node

var _dead: Dictionary = {}

func _ready() -> void:
  EventBus.entity_died.connect(_on_entity_died)
  if multiplayer.multiplayer_peer != null and not multiplayer.is_server() and not (multiplayer.multiplayer_peer is OfflineMultiplayerPeer):
    set_physics_process(false)
  else:
    set_physics_process(true)

func _physics_process(delta: float) -> void:
  if not multiplayer.is_server() and multiplayer.multiplayer_peer != null:
    return
  var to_respawn: Array = []
  for entity in _dead.keys():
    if not is_instance_valid(entity):
      to_respawn.append(entity)
      continue
    _dead[entity] -= delta
    if _dead[entity] <= 0.0:
      to_respawn.append(entity)
  for e in to_respawn:
    _dead.erase(e)
    if is_instance_valid(e) and e.is_in_group("player"):
      _respawn_player(e)

func _on_entity_died(entity: Node) -> void:
  if not is_instance_valid(entity):
    return
  if entity.is_in_group("player"):
    var t: float = float(Stats.get_stat(entity, "respawn_time", 3.0))
    _dead[entity] = t
    if entity.has_method("set_dead"):
      entity.set_dead.rpc(true)

func _respawn_player(entity: Node) -> void:
  var max_hp: float = float(Stats.get_stat(entity, "max_health", 100.0))
  var max_shield: float = float(Stats.get_stat(entity, "max_shield", 0.0))
  Stats.set_stat(entity, "health", max_hp)
  Stats.set_stat(entity, "shield", max_shield)
  EventBus.health_changed.emit(entity, max_hp, max_hp)
  EventBus.shield_changed.emit(entity, max_shield, max_shield)
  EventBus.entity_respawned.emit(entity)
  if entity.has_method("set_dead"):
    entity.set_dead.rpc(false)
  if entity.has_method("teleport_to"):
    entity.teleport_to.rpc(_village_spawn_point())

func _village_spawn_point() -> Vector3:
  var v: Variant = get_tree().get_first_node_in_group("village")
  if v is Node3D:
    return (v as Node3D).global_position + Vector3(0, 1, 0)
  return Vector3(0, 1, 0)
