extends Node3D

@export var _splash_small_sound: AudioStreamPlayer3D
@export var _splash_small_quiet_sound: AudioStreamPlayer3D
@export var _model: Node3D
@export var _splash_particles: GPUParticles3D
@export var _picking_area: Area3D
@export var body: RigidBody3D
## no longer exists and shouldn't be considered, but not ready to be freed yet
@export var is_dead := false

var _in_splash_range := {}

## something to ignore
var sender_id: int
var sender_body: PhysicsBody3D

func _ready() -> void:
	body.process_mode = Node.PROCESS_MODE_DISABLED


func _process(delta: float) -> void:
	# spin around, no need to replicate this
	_model.basis = _model.basis.rotated(Vector3(1, 0, 0), -((TAU*2) * delta))
	_model.basis = _model.basis.orthonormalized()
	
	if not is_multiplayer_authority():
		return
	
	global_position = body.global_position


@rpc("authority", "call_local", "reliable")
func _disable_body() -> void:
	# not using synchronizer for this because it ends up enabling processing
	# on other clients
	(func() -> void: body.process_mode = Node.PROCESS_MODE_DISABLED).call_deferred()
	_picking_area.collision_layer = 0


func _on_body_entered(p_body: Node3D) -> void:
	if p_body == sender_body:
		return

	if p_body.is_in_group("voids"):
		queue_free()
		return
	
	for area: Area3D in _in_splash_range:
		area.get_parent_node_3d().water.rpc_id(1, sender_id)
	
	_splash_small_sound.play()
	_splash_small_quiet_sound.play()
	_splash_particles.emitting = true
	
	is_dead = true
	_model.hide()
	_disable_body.rpc()
	await _splash_small_sound.finished
	if _splash_small_quiet_sound.playing:
		await _splash_small_quiet_sound.finished
	queue_free()


func _on_splash_area_entered(area: Area3D) -> void:
	_in_splash_range[area] = true


func _on_splash_area_exited(area: Area3D) -> void:
	_in_splash_range.erase(area)


@rpc("authority", "call_local", "reliable")
func set_global_pos(new: Vector3) -> void:
	global_position = new
	body.global_position = new
	body.reset_physics_interpolation()


@rpc("any_peer", "call_local", "reliable")
func get_picked_up() -> void:
	if is_multiplayer_authority():
		queue_free()


func mark_interactive() -> void:
	for submodel in _model.get_children():
		(submodel as MeshInstance3D).mesh.surface_get_material(0).next_pass.set("shader_parameter/color", Color.WHITE)


func mark_non_interactive() -> void:
	for submodel in _model.get_children():
		(submodel as MeshInstance3D).mesh.surface_get_material(0).next_pass.set("shader_parameter/color", Color(1, 1, 1, 0))
