extends CanvasLayer

# Top-left roster of every connected player (human + bot). White entries are
# on the local player's team (same race — races double as teams, see
# TeamSelect), red entries are the enemy team. Bots (negative peer_id, see
# bots/bot_manager.gd) get a trailing " (b)". Rebuilt whenever
# PlayerRegistry's roster changes rather than polled every frame.

const MARGIN_X := 16.0
const MARGIN_TOP := 90.0
const WIDTH := 220.0
const HEIGHT := 260.0

var _list: RichTextLabel


func _ready() -> void:
	layer = 4
	_build_ui()
	PlayerRegistry.loadout_updated.connect(_on_loadout_updated)
	PlayerRegistry.player_removed.connect(_on_player_removed)
	_refresh()


func _build_ui() -> void:
	var panel := PanelContainer.new()
	var ps := StyleBoxFlat.new()
	ps.bg_color = Color(0.02, 0.03, 0.06, 0.55)
	ps.set_corner_radius_all(6)
	panel.add_theme_stylebox_override("panel", ps)
	panel.mouse_filter = Control.MOUSE_FILTER_IGNORE
	# Anchored fully to the top-left corner (all anchors 0.0), so offsets are
	# plain absolute pixel coordinates that stay correct regardless of window
	# size — no push_opposite_anchor risk since every anchor here agrees.
	panel.anchor_left = 0.0
	panel.anchor_right = 0.0
	panel.anchor_top = 0.0
	panel.anchor_bottom = 0.0
	panel.offset_left = MARGIN_X
	panel.offset_top = MARGIN_TOP
	panel.offset_right = MARGIN_X + WIDTH
	panel.offset_bottom = MARGIN_TOP + HEIGHT
	add_child(panel)

	_list = RichTextLabel.new()
	_list.bbcode_enabled = true
	_list.scroll_active = true
	_list.scroll_following = false
	_list.mouse_filter = Control.MOUSE_FILTER_IGNORE
	_list.add_theme_font_size_override("normal_font_size", 15)
	_list.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
	_list.offset_left = 8
	_list.offset_top = 4
	_list.offset_right = -8
	_list.offset_bottom = -4
	panel.add_child(_list)


func _on_loadout_updated(_peer_id: int) -> void:
	_refresh()


func _on_player_removed(_peer_id: int, _info: Dictionary) -> void:
	_refresh()


func _refresh() -> void:
	var local_race: int = PlayerRegistry.get_info(PlayerRegistry.get_local_id()).get("race", 0)

	var peer_ids := PlayerRegistry.players.keys()
	peer_ids.sort_custom(func(a, b):
		var info_a: Dictionary = PlayerRegistry.players[a]
		var info_b: Dictionary = PlayerRegistry.players[b]
		var a_team: bool = info_a.get("race", 0) == local_race
		var b_team: bool = info_b.get("race", 0) == local_race
		if a_team != b_team:
			return a_team  # teammates first
		return String(info_a.get("name", "")).naturalnocasecmp_to(info_b.get("name", "")) < 0
	)

	var lines: Array[String] = []
	for peer_id in peer_ids:
		var info: Dictionary = PlayerRegistry.players[peer_id]
		var is_teammate: bool = info.get("race", 0) == local_race
		var color := GameConfig.team_color if is_teammate else GameConfig.enemy_color
		var name_text := _escape_bbcode(String(info.get("name", "")))
		if peer_id < 0:
			name_text += " (b)"
		lines.append("[color=#%s]%s[/color]" % [color.to_html(false), name_text])

	_list.text = "\n".join(lines)


func _escape_bbcode(s: String) -> String:
	return s.replace("[", "[lb]")
