extends CharacterBody3D

var gravity : float = ProjectSettings.get_setting("physics/3d/default_gravity")

var grabbable : bool = false
var shootable : bool = true
var weakpoint : bool = false
var rootnode : bool = true
var waitingfor : int = 0

@export var HP : float = 3
@export var weakpoint_damage : float = 5.0
@export var runner : bool = false
@export var physics_push_force : float = 1.5

var movement_speed: float = 8.0
var movement_delta: float
var path_point_margin: float = 1

var current_path_index: int = 0
var current_path_point: Vector3
var current_path: PackedVector3Array
@onready var default_3d_map_rid: RID = get_world_3d().get_navigation_map()
var startpos : Vector3
var forth : bool = false

var headoffset : Vector3
var headbone : int

var pissed : bool = false
@export var min_player_distance : float = 4.0
@export var min_ally_distance : float = 6.0
var runtarget : Vector3
@export var player : Node

# Called when the node enters the scene tree for the first time.
func _ready():
	headoffset = Vector3(0,0.2,0)
	headbone = $CharacterArmature/Skeleton3D.find_bone("Head")
	
	$CharacterArmature.rotation_degrees.y = 180
	
	rotation_degrees.y += 180
	
	player.enemies.append(self)
	
	$AnimationPlayer.play("Idle")
	
	pissed = true



func _physics_process(delta):
	if pissed and player.global_transform.origin.distance_to(runtarget) > 4:
		runtarget = player.global_transform.origin
	
	if current_path.is_empty() and NavigationServer3D.map_is_active(default_3d_map_rid):
		if runner:
			set_movement_target($waypoint.global_transform.origin)
		elif pissed and global_transform.origin.distance_to(runtarget) > 4:
			set_movement_target(runtarget)
			$chase_timer.start(1.5)
	
	move_and_slide()
	
	for i in get_slide_collision_count():
		var slaminto = get_slide_collision(i)
		if slaminto.get_collider() is RigidBody3D:
			slaminto.get_collider().apply_central_impulse(-slaminto.get_normal() * physics_push_force)
	
	if !current_path.is_empty():
		if !runner and global_transform.origin.distance_to(player.global_transform.origin) <= min_player_distance:
				clearpath()
				$chase_timer.start(1.5)
		
		if global_transform.origin.distance_to(current_path_point) <= path_point_margin:
			current_path_index += 1
			if current_path_index >= current_path.size():
				clearpath()
				if runner:
					if !forth:
						set_movement_target(startpos)
						forth = true
					elif forth:
						set_movement_target($waypoint.global_transform.origin)
						forth = false
				else:
					$chase_timer.start(1.5)
					
	"""for bud in player.enemies:
		if bud.get_instance_id() != get_instance_id() and bud.global_position.distance_to(global_position) <= min_ally_distance and bud.global_position.distance_to(player.global_position) < global_position.distance_to(player.global_position):
			clearpath()
			$queue_timer.start(3)"""

	if !current_path.is_empty() and HP > 0:
		$Head.position = headoffset + $CharacterArmature/Skeleton3D.get_bone_global_pose(headbone).origin
		
		if len(current_path) > 0:
			current_path_point = current_path[current_path_index]
			
			var direction = global_transform.origin.direction_to(current_path_point)
			var acceleration = 8.0

			velocity.x = lerp(velocity.x, direction.x * movement_speed, acceleration * delta)
			velocity.z = lerp(velocity.z, direction.z * movement_speed, acceleration * delta)
			
			global_transform = global_transform.interpolate_with(global_transform.looking_at(Vector3(current_path_point.x,global_position.y,current_path_point.z)), 0.2)
	
	elif current_path.is_empty() or waitingfor != 0:
		velocity.x = 0
		velocity.z = 0
	
	if HP > 0:
		var velocityclamp = 0.25
		if abs(velocity.x) + abs(velocity.z) > (velocityclamp * 2):
			$AnimationPlayer.play("Run")
		else:
			$AnimationPlayer.play("Idle")
	else:
		velocity = Vector3(0,0,0)
	
	if not is_on_floor():
		velocity.y -= gravity * delta


func deal_damage(damage):
	print(str(damage)+" damage taken, "+str(HP)+" HP left")
	HP = HP - damage
	if HP <= 0:
		print("death")
		$AnimationPlayer.play("Death")


func set_movement_target(target_position: Vector3):
	var start_position: Vector3 = global_transform.origin

	current_path = NavigationServer3D.map_get_path(
		default_3d_map_rid,
		start_position,
		target_position,
		true
	)

	if not current_path.is_empty():
		current_path_index = 0
		current_path_point = current_path[0]

func clearpath():
	current_path = []
	current_path_index = 0
	current_path_point = global_transform.origin

func _on_animation_player_animation_finished(anim_name):
	if anim_name == "Idle":
		$AnimationPlayer.play("Idle")
	if anim_name == "Run":
		$AnimationPlayer.play("Run")
	if anim_name == "Death":
		delete_me()
		"""set_collision_layer_value(1, false)
		$Head.set_collision_layer_value(1, false)"""

func delete_me():
	player.enemies.erase(self)
	get_parent().remove_child(self)
	queue_free()

func _on_chase_timer_timeout():
	if player.global_transform.origin.distance_to(runtarget) > 4:
		runtarget = player.global_transform.origin
	if global_transform.origin.distance_to(runtarget) > 4:
		set_movement_target(runtarget)
		print("updating runtarget to "+str(runtarget))
		$chase_timer.start(1.5)


func _on_queue_timer_timeout():
	$queue_timer.stop()
	_on_chase_timer_timeout()
