extends Node

var aggro_tables: Dictionary = {}
var players_in_range: Dictionary = {}

func add_aggro(enemy: Node, player: Node, amount: float) -> void:
  if enemy not in aggro_tables:
    aggro_tables[enemy] = {}
  if player in aggro_tables[enemy]:
    aggro_tables[enemy][player] += amount
  else:
    aggro_tables[enemy][player] = amount

func remove_aggro(enemy: Node, player: Node, amount: float) -> void:
  if enemy in aggro_tables and player in aggro_tables[enemy]:
    aggro_tables[enemy][player] -= amount
    if aggro_tables[enemy][player] <= 0:
      aggro_tables[enemy].erase(player)

func add_player_in_range(enemy: Node, player: Node) -> void:
  if enemy not in players_in_range:
    players_in_range[enemy] = []
  if player not in players_in_range[enemy]:
    players_in_range[enemy].append(player)

func remove_player_in_range(enemy: Node, player: Node) -> void:
  if enemy in players_in_range:
    players_in_range[enemy].erase(player)

func is_player_in_any_range(player: Node) -> bool:
  for enemy in players_in_range:
    if is_instance_valid(enemy) and player in players_in_range[enemy]:
      return true
  return false

func get_top_target(table: Dictionary) -> Node:
  var top: Node = null
  var top_val := 0.0
  for player in table:
    if is_instance_valid(player) and table[player] > top_val:
      top_val = table[player]
      top = player
  return top

func update_target(enemy: Node) -> void:
  var table: Dictionary = aggro_tables[enemy]
  var top: Node = get_top_target(table)
  var data_source: Node = _get_data_source(enemy)
  if not data_source:
    return
  var state: int = data_source.get_stat(enemy, "state")
  if top and top != data_source.get_stat(enemy, "target"):
    data_source.set_stat(enemy, "target", top)
    if state == 0 or state == 3:
      data_source.set_stat(enemy, "state", 1)
  elif not top and state != 0 and state != 3:
    data_source.set_stat(enemy, "target", null)
    data_source.set_stat(enemy, "state", 3)

func get_enemies_in_radius(source: Node, radius: float) -> Array:
  var result: Array = []
  for enemy in get_tree().get_nodes_in_group("enemies"):
    if enemy != source and is_instance_valid(enemy):
      var dist: float = source.global_position.distance_to(enemy.global_position)
      if dist <= radius:
        result.append(enemy)
  return result

func get_alert_radius(entity: Node) -> float:
  var data_source: Node = _get_data_source(entity)
  if data_source:
    var base: EnemyStats = data_source.get_base(entity)
    if base:
      return base.alert_radius
  return 10.0

func erase_entity(entity: Node) -> void:
  aggro_tables.erase(entity)
  players_in_range.erase(entity)
  for enemy in aggro_tables:
    if is_instance_valid(enemy):
      aggro_tables[enemy].erase(entity)
      var data_source: Node = _get_data_source(enemy)
      if data_source and data_source.get_stat(enemy, "target") == entity:
        data_source.set_stat(enemy, "target", null)
        data_source.set_stat(enemy, "state", 3)
  for enemy in players_in_range:
    if is_instance_valid(enemy):
      players_in_range[enemy].erase(entity)

func _get_data_source(entity: Node) -> Node:
  if entity.is_in_group("boss"):
    return BossData
  elif entity.is_in_group("enemies"):
    return EnemyData
  return null
