extends Sprite3D

const SLIDE_DURATION := 0.25
const UP_DURATION := 0.1
const HOLD_DURATION := 0.05
const DOWN_DURATION := 0.18

var _open_button: Node3D
var _close_button: Node3D
var _target_button: Node3D
var _close_rest_x: float
var _open_rest_x: float
var _rest_y: float
var _slide_tween: Tween
var _press_tween: Tween

func _ready() -> void:
	if not get_parent().is_node_ready():
		await get_parent().ready
	await get_tree().process_frame
	_open_button = get_parent().get_node("DoorOpen")
	_close_button = get_parent().get_node("DoorClose")
	_close_rest_x = _project_to_hand_plane(_close_button)
	_open_rest_x = _project_to_hand_plane(_open_button)
	_rest_y = position.y
	_target_button = _close_button
	position = Vector3(_close_rest_x, _rest_y, position.z)
	print("[VirtuaHand] close_x=", _close_rest_x, " open_x=", _open_rest_x, " hand_pos=", position)

	EventBus.button_pressed.connect(_animate_press)
	EventBus.active_button_changed.connect(_on_active_button_changed)

func _project_to_hand_plane(button: Node3D) -> float:
	var cam := get_viewport().get_camera_3d()
	if not cam:
		return button.position.x
	var screen_pos := cam.unproject_position(button.global_position)
	var ray_origin := cam.project_ray_origin(screen_pos)
	var ray_dir := cam.project_ray_normal(screen_pos)
	if absf(ray_dir.z) < 0.0001:
		return button.position.x
	var t := (global_position.z - ray_origin.z) / ray_dir.z
	var hit := ray_origin + ray_dir * t
	return get_parent().to_local(hit).x

func _on_active_button_changed(target: String) -> void:
	var new_button: Node3D = _open_button if target == "open" else _close_button
	if new_button == _target_button:
		return
	_target_button = new_button
	var target_x: float = _open_rest_x if target == "open" else _close_rest_x
	print("[VirtuaHand] slide target=", target, " target_x=", target_x, " current_pos=", position)
	if _press_tween and _press_tween.is_valid():
		_press_tween.kill()
	if _slide_tween and _slide_tween.is_valid():
		_slide_tween.kill()
	_slide_tween = create_tween()
	_slide_tween.tween_property(self, "position:x", target_x, SLIDE_DURATION).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)

func _animate_press() -> void:
	if not is_instance_valid(_target_button):
		return
	if _press_tween and _press_tween.is_valid():
		_press_tween.kill()
	var fingertip_offset := texture.get_height() * 0.5 * pixel_size * scale.y
	var press_y := _target_button.position.y - fingertip_offset
	_press_tween = create_tween()
	_press_tween.tween_property(self, "position:y", press_y, UP_DURATION).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_OUT)
	_press_tween.tween_interval(HOLD_DURATION)
	_press_tween.tween_property(self, "position:y", _rest_y, DOWN_DURATION).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN)
