extends Node

const AURA_REFRESH := 0.5

var active_auras: Dictionary = {}

func _ready() -> void:
  EventBus.role_changed.connect(_on_role_changed)
  EventBus.entity_died.connect(_on_entity_died)

func _process(_delta: float) -> void:
  for entity in active_auras.keys():
    if not is_instance_valid(entity):
      active_auras.erase(entity)
      continue
    for aura in active_auras[entity]:
      _propagate(entity, aura)

func _propagate(source_entity: Node, aura: Effect) -> void:
  if not source_entity is Node3D:
    return
  var buff_system: Node = get_node("../BuffSystem")
  var players := get_tree().get_nodes_in_group("player")
  for player in players:
    if not is_instance_valid(player) or not PlayerData.alive:
      continue
    var dist: float = source_entity.global_position.distance_to(player.global_position)
    if dist > aura.aura_radius:
      continue
    if buff_system.has_aura_buff(player, aura.effect_name, source_entity):
      buff_system.refresh_aura_buff(player, aura.effect_name, source_entity, AURA_REFRESH)
    else:
      var buff := Effect.new()
      buff.effect_name = aura.effect_name
      buff.type = Effect.Type.BUFF
      buff.stat = aura.stat
      buff.value = aura.value
      buff.duration = AURA_REFRESH
      buff.is_multiplier = aura.is_multiplier
      buff_system.apply_aura_buff(player, buff, source_entity)

func _on_role_changed(player: Node, _role_type: int) -> void:
  active_auras.erase(player)
  var ability_set: AbilitySet = PlayerData.ability_set
  if not ability_set:
    return
  for ability in ability_set.abilities:
    if ability and ability.type == Ability.Type.PASSIVE:
      var effect := Effect.new()
      effect.effect_name = ability.ability_name
      effect.type = Effect.Type.AURA
      effect.stat = ability.passive_stat
      effect.value = ability.damage / 100.0
      effect.duration = -1.0
      effect.is_multiplier = true
      effect.aura_radius = ability.ability_range
      if not active_auras.has(player):
        active_auras[player] = []
      active_auras[player].append(effect)

func _on_entity_died(entity: Node) -> void:
  active_auras.erase(entity)
