@tool
extends Node2D

##是否要自动的向其子集中添加一个PropComp
@export var auto_attach_prop_component := true

##是否要输出Debug Message
@export var debug_log := true

##输出一个ID的前缀，方便策划调整
const PREFIX := "[Prop_%04d]"

func _ready() -> void:
	if not Engine.is_editor_hint():
		return
	
	_ensure_existing_props()
	child_entered_tree.connect(_on_child_entered_tree)

	# 强制让 Editor 重新计算 configuration warnings
	update_configuration_warnings()

func _on_child_entered_tree(node: Node) -> void:
	if not Engine.is_editor_hint():
		return

	_try_attach_and_assign(node)

	# 子节点变化后，刷新 Inspector 警告
	update_configuration_warnings()

func _ensure_existing_props() -> void:
	for child in get_children():
		_try_attach_and_assign(child)

func _try_attach_and_assign(prop: Node) -> void:
	if not auto_attach_prop_component:
		return
	if prop == null:
		return
	if prop is PropComponent:
		return

	var comp := _find_prop_component_top(prop)
	if comp == null:
		comp = PropComponent.new()
		comp.name = "PropComponent" # 临时名
		prop.add_child(comp)
		comp.owner = get_tree().edited_scene_root

	# 确保 prop_id 唯一且有效
	if int(comp.prop_id) < 0 or _is_prop_id_used_elsewhere(int(comp.prop_id), comp):
		comp.prop_id = _alloc_prop_id()

	# 用 prop_id 重命名 PropComponent
	comp.name = PREFIX % int(comp.prop_id)

	if debug_log:
		print("[PropManager][Editor] Ensure PropComponent:", prop.name, "->", comp.name, "id=", comp.prop_id)

func _find_prop_component_top(prop: Node) -> PropComponent:
	for child in prop.get_children():
		if child is PropComponent:
			return child as PropComponent
	return null

func _alloc_prop_id() -> int:
	var max_id := -1

	for prop in get_children():
		var comp := _find_prop_component_top(prop)
		if comp == null:
			continue
		max_id = maxi(max_id, int(comp.prop_id))

	return max_id + 1

func _is_prop_id_used_elsewhere(prop_id: int, self_comp: PropComponent) -> bool:
	for prop in get_children():
		var comp := _find_prop_component_top(prop)
		if comp == null:
			continue
		if comp == self_comp:
			continue
		if int(comp.prop_id) == prop_id:
			return true
	return false

# =====================================================
# Editor Configuration Warnings（Inspector 黄色警告）
# =====================================================
func _get_configuration_warnings() -> PackedStringArray:
	var warnings := PackedStringArray()

	if not Engine.is_editor_hint():
		return warnings

	for prop in get_children():
		if prop is PropComponent:
			continue

		var comp := _find_prop_component_top(prop)
		if comp == null:
			warnings.append(
				"Prop '%s' has no PropComponent as a top-level child." % prop.name
			)

	return warnings
