class_name UnitHelper
extends Object

## 유닛 외형 렌더링 및 3D 장착 어태치먼트 제어를 위한 정적 유틸리티 헬퍼

## 자식 메쉬에 지정된 텍스처를 씌우는 재귀 함수
static func apply_skin(node: Node, texture_path: String) -> void:
	if not ResourceLoader.exists(texture_path):
		return
		
	var texture: Texture2D = load(texture_path) as Texture2D
	if not texture:
		return
		
	_apply_skin_recursive(node, texture)

static func _apply_skin_recursive(node: Node, texture: Texture2D) -> void:
	if node is MeshInstance3D:
		var mesh_inst: MeshInstance3D = node as MeshInstance3D
		var mat: StandardMaterial3D = StandardMaterial3D.new()
		mat.albedo_texture = texture
		mat.roughness = 0.5
		mesh_inst.material_override = mat
	for child: Node in node.get_children():
		_apply_skin_recursive(child, texture)

## 자식 노드 중 AnimationPlayer 탐색
static func find_animation_player(node: Node) -> AnimationPlayer:
	if node is AnimationPlayer:
		return node as AnimationPlayer
	for child: Node in node.get_children():
		var res: AnimationPlayer = find_animation_player(child)
		if res:
			return res
	return null

## 자식 노드 중 Skeleton3D 탐색
static func find_skeleton(node: Node) -> Skeleton3D:
	if node is Skeleton3D:
		return node as Skeleton3D
	for child: Node in node.get_children():
		var res: Skeleton3D = find_skeleton(child)
		if res:
			return res
	return null

## 유닛의 오른손에 지정된 무기 모델을 런타임 장착
static func attach_weapon(model_instance: Node3D, unit_data: UnitData) -> void:
	if not model_instance or not unit_data:
		return
		
	# 스켈레톤 노드 탐색
	var skeleton: Skeleton3D = find_skeleton(model_instance)
	if not skeleton:
		return
		
	# 오른손 본("RightHand")이 존재하는지 확인
	var bone_idx: int = skeleton.find_bone("RightHand")
	if bone_idx == -1:
		print("UnitHelper: RightHand bone not found in skeleton.")
		return
		
	# 이미 장착된 무기가 있는지 확인하여 제거 (중복 장착 방지)
	var existing_attachment: Node = skeleton.get_node_or_null("RightHandAttachment")
	if existing_attachment:
		existing_attachment.queue_free()
		
	# 1. BoneAttachment3D 노드 동적 생성 및 본 동기화 설정
	var bone_attachment: BoneAttachment3D = BoneAttachment3D.new()
	bone_attachment.name = "RightHandAttachment"
	bone_attachment.bone_name = "RightHand"
	skeleton.add_child(bone_attachment)
	
	# 2. 유닛 종류에 따른 무기 설정 분기
	var weapon_scene_path: String = ""
	var weapon_scale: Vector3 = Vector3.ONE
	var weapon_rotation: Vector3 = Vector3.ZERO
	var weapon_position: Vector3 = Vector3.ZERO
	var texture_path: String = ""
	
	if unit_data.unit_id == "Unit_Guardian":
		# 가디언 창 (azure_spear)
		weapon_scene_path = "res://assets/models/items/weapons/azure_spear.fbx"
		texture_path = "res://assets/models/items/weapons/azure_spear_0.png"
	else:
		# 기본값: Striker 검 (azure_blade)
		weapon_scene_path = "res://assets/models/items/weapons/azure_blade.fbx"
		texture_path = "res://assets/models/items/weapons/azure_blade_0.png"
		
	# 3. 무기 로드 및 인스턴스화
	if ResourceLoader.exists(weapon_scene_path):
		var weapon_scene: PackedScene = load(weapon_scene_path) as PackedScene
		if weapon_scene:
			var weapon_inst: Node3D = weapon_scene.instantiate() as Node3D
			weapon_inst.scale = weapon_scale
			weapon_inst.rotation_degrees = weapon_rotation
			weapon_inst.position = weapon_position
			
			# 무기 텍스처 매핑
			apply_skin(weapon_inst, texture_path)
			bone_attachment.add_child(weapon_inst)
			print("UnitHelper: Attached weapon successfully. Unit: ", unit_data.unit_name, ", Weapon: ", weapon_scene_path.get_file())

## 애니메이션 내에서 모델의 로컬 정면 방향을 강제 리셋하는 루트(Armature) 트랙 정화
static func clean_root_animation_tracks(anim_player: AnimationPlayer) -> void:
	if not anim_player:
		return
		
	# AnimationPlayer에 바인딩된 모든 애니메이션 라이브러리의 트랙 정화
	for library_name: StringName in anim_player.get_animation_library_list():
		var lib: AnimationLibrary = anim_player.get_animation_library(library_name)
		if not lib:
			continue
			
		for anim_name: StringName in lib.get_animation_list():
			var anim: Animation = lib.get_animation(anim_name)
			if anim:
				var tracks_to_remove: Array[int] = []
				for track_idx: int in range(anim.get_track_count()):
					var path_str: String = str(anim.track_get_path(track_idx))
					# 최상위 루트 노드(Armature 등)의 회전/위치 강제 덮어쓰기 트랙 검출
					# Skeleton3D 하위의 실제 뼈대 애니메이션 트랙은 유지하고 오직 Armature 루트 트랜스폼 트랙만 제거
					if path_str == "Armature:rotation" or path_str == "Armature:position" or \
					   path_str.begins_with("Armature:") and not "Skeleton3D" in path_str:
						tracks_to_remove.append(track_idx)
						
				# 역순으로 정렬하여 트랙 제거 시 인덱스 밀림 방지
				tracks_to_remove.reverse()
				for track_idx: int in tracks_to_remove:
					anim.remove_track(track_idx)
					
	print("UnitHelper: Cleaned root and Armature transform tracks to preserve character body rotation.")
