extends MeshInstance3D

@export_category("References")
@export var vr_camera: Camera3D  # The VR camera (child of the XR Origin)
@export_category("Settings")
@export var distance: float = 1.5  # How far from the camera the target should appear
@export var headlocked: bool = false
@export var offset: Vector3 = Vector3()
@export var offset_rotation: int = 180

func _process(_delta):
	# Update the position every frame
	reposition_rig()

func reposition_rig():
	distance = clampf(distance, 0.001, 1000)
	
	if vr_camera == null:
		printerr("VR Camera is not assigned.")
		return
	
	# Get the original scale
	var original_scale = global_transform.basis.get_scale()
	if headlocked:
		# Get the camera's transform (rotation and position)
		var cam_transform = vr_camera.global_transform.orthonormalized()
		# Apply the camera's rotation and position
		global_position = (cam_transform.origin + cam_transform.basis.z * -distance) + (cam_transform.basis * offset)
		
		# Set the object's rotation to match the camera's rotation
		global_rotation = cam_transform.basis.get_euler()
		
		# Preserve the original scale
		scale = original_scale
		return

	# 1. Get the camera's current forward direction (world space)
	# In Godot, -Z is forward, so we negate the Z basis vector
	var camera_forward = -vr_camera.global_transform.basis.z
	
	# 2. We want to use the horizontal component of the camera's forward direction
	# This prevents vertical "headlocking" while maintaining the correct distance
	var camera_forward_horizontal = Vector3(0, 0, camera_forward.z).normalized()
	
	# Projection for relative offsets (excluding Y)
	var camera_projected = camera_forward.project(Vector3(1, 0, 1)).normalized()
	camera_projected.y = 1
	
	# 3. Calculate the desired position in front of the camera
	var target_position = vr_camera.global_position + camera_forward_horizontal * distance
	
	# 4. Set the mesh instance position to that location
	global_position = target_position + (offset * camera_projected)
	
	# Orient to look at camera
	var flat_camera_pos = vr_camera.global_position + (offset * camera_projected)
	flat_camera_pos.y = global_position.y # Flatten look at to object's height (so it does not tilt upwards or downwards)
	
	look_at(flat_camera_pos, Vector3.UP)
	rotate_y(deg_to_rad(offset_rotation))
	
	# Preserve the original scale
	scale = original_scale
