@tool
extends Node
class_name ReedSceneID

##此Scene的描述ID，无法主动修改，你可以向編輯器申請。
@export_custom(
	PROPERTY_HINT_NONE, 
	"", 
	PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_READ_ONLY
) 
var scene_id: int  = -1:
	set(value):
		if _scene_id == value:
			return
		_scene_id = value
		if Engine.is_editor_hint():
			_sync_node_name()
			update_configuration_warnings()
	get():
		return _scene_id

var _scene_id: int = -1
var _is_syncing_name := false

const DB_PATH := "res://addons/reedscene/demo/data_base/GLOBAL_SCENE_ID.tres"

## ==============================
## Build In
## ==============================

## 進入Tree
func _enter_tree() -> void:
	if Engine.is_editor_hint():
		_sync_node_name()

## 初始化完成后
func _ready() -> void:
	if Engine.is_editor_hint():
		renamed.connect(func():
			_sync_node_name()
		)

func has_id() -> bool:
	return scene_id >= 0

func _get_display_name() -> String:
	if not has_id():
		return "[Invalid!]"
	return "[ID: %d]" % scene_id

func _sync_node_name() -> void:
	if _is_syncing_name:
		return

	_is_syncing_name = true

	var desired := _get_display_name()
	if name != desired:
		name = desired

	_is_syncing_name = false

func _get_configuration_warnings() -> PackedStringArray:
	var warnings := PackedStringArray()

	# 1️. 结构校验（只跟 Node 结构有关）
	var parent := get_parent()
	if parent == null or not (parent is ReedScene):
		warnings.append("ReedSceneID must be a child of ReedScene.")
		return warnings

	# 2️. 自身状态
	if not has_id():
		warnings.append("Scene ID is not assigned.")
		return warnings

	# 3️. DB 一致性校验（委托给 DB）
	var scene_path := parent.scene_file_path
	if scene_path.is_empty():
		warnings.append("Parent scene is not saved; cannot validate Scene ID.")
		return warnings

	var uid := ResourceUID.path_to_uid(scene_path)

	var db := load(DB_PATH) as SceneIDDatabase
	if not db:
		warnings.append("SceneIDDatabase not found.")
		return warnings

	var result := db.validate_scene_id(scene_id, uid, scene_path)
	if result == null:
		return warnings
	
	for msg in result.messages:
		warnings.append(msg)

	return warnings

## 獲取Scene id的接口
func get_scene_id() ->int:
	return _scene_id
