class_name GrappingHook extends Node2D

@export var min_rope_length := 20
@export var max_rope_length := 200

@onready var anchor: StaticBody2D = %Anchor
@onready var pin_joint_2d: PinJoint2D = %PinJoint2D
@onready var player_anchor: RigidBody2D = %PlayerAnchor
@onready var line_2d: Line2D = %Line2D

const speed = 30

var _binded_hook_comp:SpawnHookComponet
var m_update_rope_with_nodes: bool = false

func init(hook_comp:SpawnHookComponet):
	_binded_hook_comp = hook_comp

##默认以PLAYER类开始Hook
func start_hook(hookPosition):
	anchor.global_position = hookPosition
	
	var player = get_tree().get_first_node_in_group("PLAYER") as CharacterBody2D
	player_anchor.global_position = player.global_position
	player.reparent(player_anchor)

##以注册者开始Hook
func start_hook_with_instigator(hookPosition:Vector2,instigator:Node2D):
	anchor.global_position = hookPosition
	
	var i = instigator
	if not i: return
	
	player_anchor.global_position = i.global_position
	i.reparent(player_anchor)

##离开Hook
func _leave_rope():
	await get_tree().create_timer(.1).timeout
	
	var player: Node2D
	if _binded_hook_comp:
		player = _binded_hook_comp.component_owner
	
	player.reparent(get_tree().current_scene)
	#player.set_active(true)
	player.rotation = 0
	
	queue_free()

##此函數通過外部的修改可以驅動物體在繩子上移動。
func move_hook(input_dir: Vector2, delta: float) -> void:
	if input_dir == Vector2.ZERO:
		return

	var distance_to_anchor := player_anchor.global_position.distance_to(anchor.global_position)

	# === 左右摆动（切向力）===
	if input_dir.x != 0.0:
		var tangent := player_anchor.global_transform.x
		player_anchor.apply_central_impulse(
			tangent * input_dir.x * speed * delta
		)

	# === 上下：改变绳长 ===
	if input_dir.y != 0.0:
		# y < 0 → 上（收绳）
		# y > 0 → 下（放绳）
		var rope_dir := player_anchor.global_transform.y as Vector2
		var rope_delta := rope_dir * input_dir.y * speed * delta * 0.5 as Vector2

		if input_dir.y > 0.0 and distance_to_anchor >= max_rope_length:
			return
		if input_dir.y < 0.0 and distance_to_anchor <= min_rope_length:
			return

		# 暂时解绑 joint，手动移动 anchor
		pin_joint_2d.node_b = NodePath("")
		player_anchor.global_position += rope_delta
		pin_joint_2d.node_b = player_anchor.get_path()

##更新特定点的位置
func update_line_target_pos_with_index(point_index: int, target_pos: Vector2) -> void:
	line_2d.set_point_position(
		point_index,
		target_pos - global_position
	)

##更新锚点的位置
func update_line_anchor_pos(target_pos: Vector2) -> void:
	update_line_target_pos_with_index(0,target_pos)

##重置所有点的位置到指定的位置
func reset_line_points_to_target(target_pos: Vector2)-> void:
	for i in range(line_2d.points.size()):
		update_line_target_pos_with_index(i, target_pos)

func _process(delta: float) -> void:
	##如果不更新，直接返回。
	if not m_update_rope_with_nodes: return
	
	update_line_target_pos_with_index(0,player_anchor.global_position)
	update_line_target_pos_with_index(1,anchor.global_position)
