class_name Ball
extends StaticBody2D

@onready var raycast: RayCast2D = $RayCast2D
@onready var sprite: Sprite2D = $Sprite2D
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var map: MainLevel = get_tree().root.get_child(0).get_node("TileMap")
@onready var tile_map: TileMapLayer = get_tree().root.get_child(0).get_node("TileMap/TileMapLayer")

@export var start_position: Node2D
@export var movement_dir: Vector2 = Vector2(0, 0)
@export var puzzle: BallCoursePuzzle
@export var can_roll := false
@export var speed := 0.35
var input_dir: Vector2
var is_moving := false
var _default_can_roll := false

# Called when the node enters the scene tree for the first time.
func _ready():
	input_dir = movement_dir.normalized()
	_default_can_roll = can_roll
	animation_player.speed_scale = (speed / 0.4) * input_dir.x
	reset()

func _physics_process(delta):
	_try_move(delta)

func _process(delta):
	if can_roll:
		if not animation_player.is_playing():
			animation_player.play(&"roll")
		
		if is_moving:
			return
		
		raycast.target_position = input_dir * 8
		raycast.force_raycast_update()
		var collider: Node2D = raycast.get_collider()
		
		if collider and collider.is_in_group("fake_wall"):
			collider.queue_free()
			queue_free()
		
		if raycast.is_colliding():
			return
		
		var current_tile: Vector2i = tile_map.local_to_map(global_position)
		var target_tile: Vector2i = Vector2i(
			current_tile.x + input_dir.x, 
			current_tile.y + input_dir.y
		)
		
		global_position = tile_map.map_to_local(target_tile)

		var is_death_tile = map.is_death_tile(global_position)
		if is_death_tile:
			reset()
			return
			
		is_moving = true
		sprite.global_position = tile_map.map_to_local(current_tile)

func _try_move(delta: int):
	if not is_moving:
		return
	
	sprite.global_position = sprite.global_position.move_toward(global_position, speed)
	
	if global_position == sprite.global_position:
		is_moving = false
		return

func reset():
	can_roll = _default_can_roll
	animation_player.stop()
	global_position = start_position.global_position

func _on_area_entered(area: Area2D):
	if area.is_in_group("death"):
		if puzzle:
			puzzle.reset()
