extends Node2D
class_name Bunny

@export var animation_player : AnimationPlayer
@export var min_distance_to_player := 20.0
@export var max_distance_to_player := 500.0
@export var agent : NavigationAgent2D
@export var speed := 3.0

var health : int
var team : int
var player : Node2D

var on_death_callbacks : Array
var move_velocity : Vector2

var next_location : Vector2
var randomized_next_location : Vector2
var dir : Vector2

var time_since_got_player := 100.0
var time_since_got_move_location := 100.0
var last_player_velocity := 0.0
var last_target_position : Vector2

var max_pos_check_time := 0.5
var max_pos_check_time_inactive_scalar := 10.0
var max_get_move_location_time := 0.125

var random_goal_spread_factor := 2.5
var random_move_location_spread_factor := 8.0
var random_angle_change := deg_to_rad(4.0)

func _ready():
	pass
	
func _physics_process(delta):
	randomize()
	
	if abs(player.velocity.length() - last_player_velocity) > 100.0:
		time_since_got_player = max_pos_check_time
	if time_since_got_player >= max_pos_check_time and player.velocity.length() > 0.1:
		time_since_got_player = randf() * max_pos_check_time * 0.5
		update_target_pos()
	if time_since_got_player >= max_pos_check_time * max_pos_check_time_inactive_scalar and player.velocity.length() < 0.1:
		time_since_got_player = -(randf() * max_pos_check_time * 0.5)
		update_target_pos()
	if self.global_position.distance_to(player.global_position) < max_distance_to_player and time_since_got_move_location > max_get_move_location_time:
		time_since_got_move_location = 0
		if  agent.is_target_reachable():
			next_location = agent.get_next_path_position()
			randomized_next_location = next_location + Vector2(randf() - 0.5, randf() - 0.5 ) * 2 * random_move_location_spread_factor
		dir = self.global_position.direction_to(randomized_next_location).normalized().rotated((randf() - 0.5) * 2 * random_angle_change)
	if self.global_position.distance_to(player.global_position) >= min_distance_to_player:
		move_velocity = dir * delta * 60 * speed
		update_animation()
		if self.global_position.distance_to(next_location) < move_velocity.length():
			self.global_position = next_location
			time_since_got_player = 10.0
			time_since_got_move_location = 10.0
		else:
			self.translate(move_velocity)
	else:
		animation_player.stop()
	time_since_got_player += delta
	time_since_got_move_location += delta
	last_player_velocity = player.velocity.length()
	last_target_position = agent.target_position
	pass
	
func update_target_pos():
	agent.target_position = Vector2(player.global_position) + Vector2(randf() - 0.5 , randf() - 0.5) *  2 * random_goal_spread_factor
	pass

func damage(damage_amount : int):
	health -= damage_amount
	if(health <= 0): on_death()
	pass
	
func heal(health_amount : int):
	self.health += health_amount
	pass

func on_death():
	for callback in on_death_callbacks:
		callback.call(self)
	pass
	
func sub_on_death(callback : Callable):
	on_death_callbacks.push_front(callback)
	pass

func update_animation():
	match self.move_velocity:
		Vector2.ZERO: animation_player.play("Idle")
		_: 
			var left_dot = Vector2.LEFT.dot(self.move_velocity)
			var right_dot = Vector2.RIGHT.dot(self.move_velocity)
			var up_dot = Vector2.UP.dot(self.move_velocity)
			var down_dot = Vector2.DOWN.dot(self.move_velocity)
			
			var max_dot = maxf(left_dot, maxf(right_dot, maxf(up_dot, down_dot)))
			match max_dot:
				left_dot: animation_player.play("MoveLeft") 
				right_dot: animation_player.play("MoveRight") 
				up_dot: animation_player.play("MoveUp") 
				down_dot: animation_player.play("MoveDown") 
	pass
