@tool
class_name PlayerSpawnPoint
extends Marker3D

@export var spawn_index: int = 0: set = set_spawn_index
@export_tool_button("Set unique index") var set_unique_index: Callable = func() -> void:
			for spawn_point: PlayerSpawnPoint in spawn_points:
				if spawn_point == self:
					continue
				
				if spawn_point.spawn_index == spawn_index:
					set_spawn_index(spawn_index + 1)
					set_unique_index.call()
					return
			
			update_configuration_warnings()
@export var editor_auto_assign_unique_id: bool = true

static var spawn_points: Array[PlayerSpawnPoint] = []
var idx_label: Label3D
var config_warnings_hint: Label3D


func _init() -> void:
	if Engine.is_editor_hint():
		var player_scene: PackedScene = load("res://components/characters/player/player_character.tscn")
		add_child(player_scene.instantiate(), false, Node.INTERNAL_MODE_FRONT)
		
		# Setup labels.
		idx_label = Label3D.new()
		idx_label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
		idx_label.shaded = false
		idx_label.font_size = 64
		add_child(idx_label, false, Node.INTERNAL_MODE_FRONT)
		idx_label.position.y = 1.8
		set_spawn_index(spawn_index)
		
		config_warnings_hint = Label3D.new()
		config_warnings_hint.billboard = BaseMaterial3D.BILLBOARD_ENABLED
		config_warnings_hint.shaded = false
		config_warnings_hint.no_depth_test = true
		config_warnings_hint.fixed_size = true
		config_warnings_hint.text = "!"
		config_warnings_hint.modulate = Color.RED
		add_child(config_warnings_hint, false, Node.INTERNAL_MODE_FRONT)
		config_warnings_hint.position.y = 1.0
		
		var tween: Tween = create_tween().set_loops()
		tween.tween_property(config_warnings_hint, ^"scale", Vector3.ONE * 1.5, 0.075)
		tween.tween_property(config_warnings_hint, ^"scale", Vector3.ONE * 1.0, 0.075)
		
		update_configuration_warnings()


func _enter_tree() -> void:
	if not spawn_points.has(self):
		spawn_points.append(self)
	
	if editor_auto_assign_unique_id and Engine.is_editor_hint():
		set_unique_index.call_deferred()


func _exit_tree() -> void:
	spawn_points.erase(self)


func set_spawn_index(index: int) -> void:
	spawn_index = index
	update_configuration_warnings()
	
	if is_instance_valid(idx_label):
		idx_label.text = str(spawn_index)


func make_current(do_autosave: bool = true) -> void:
	GameGlobals.spawn_index = spawn_index

	if do_autosave:
		SaveManager.save_game()


static func get_spawn_point_by_index(index: int) -> PlayerSpawnPoint:
	for spawn_point: PlayerSpawnPoint in PlayerSpawnPoint.spawn_points:
		if spawn_point.spawn_index == index:
			return spawn_point
	
	return null


func _get_configuration_warnings() -> PackedStringArray:
	var warnings: PackedStringArray = []
	
	for spawn_point: PlayerSpawnPoint in spawn_points:
		if spawn_point.spawn_index == spawn_index and spawn_point != self:
			warnings.append(str(spawn_point, " has the same spawn index as us."))
			spawn_point.config_warnings_hint.show()
		
		spawn_point.update_configuration_warnings()
	
	if warnings.is_empty():
		config_warnings_hint.hide()
	
	return warnings
