class_name MechEnemy extends MechCharacter

@export var target: MechCharacter
@export var max_heat: float = 100.0
@export var max_damage: float = 100.0
@export var max_structure: int = 5

var heat: float = 0.0:
	set(value):
		# TODO Check for heat condition
		heat = value
var damage: float = 0.0:
	set(value):
		# TODO Check for damage conditions
		damage = value
var structure: int = max_structure:
	set(value):
		# TODO Check for structure conditions
		structure = value

var target_detected: bool = false

@onready var nav_agent: NavigationAgent3D = $NavigationAgent3D
@onready var vision_cone: VisionCone = %VisionCone

# gdlint: disable=class-definitions-order
var target_position: Vector3:
	set(value):
		nav_agent.target_position = value
	get:
		return nav_agent.target_position
# gdlint: enable=class-definitions-order


func _actor_setup() -> void:
	# Wait for the first physics frame so the navserver can sync
	await get_tree().physics_frame
	set_physics_process(true)


func _ready() -> void:
	vision_cone.excluded = [self, target]
	# Disable physics processing to give the navserver time to sync
	set_physics_process(false)
	# Can't await during _ready, so defer the call with the await
	call_deferred("_actor_setup")


func deal_damage(delta: float) -> void:
	damage += delta


func deal_heat(delta: float) -> void:
	heat += delta


func deal_structure(delta: int) -> void:
	structure += delta


func _physics_process(delta: float) -> void:
	var delta_factor: float = delta * GameState.TARGET_FPS

	if target and target_detected and not target.in_shadow():
		target_position = target.global_position

	var relative_target: Vector3 = target_position - global_position
	var angle_to_target: float = atan2(relative_target.x, relative_target.z)

	if Input.is_action_just_pressed("ui_menu"):
		print("breakpoint...")

	var movement: Vector3 = (
		(nav_agent.get_next_path_position() - global_position).normalized()
		if relative_target.length() > 5
		else Vector3.ZERO
	)

	if movement:
		# Slowly turn mesh towards camera vector when moving on ground
		if is_on_floor():
			mesh.global_rotation.y = lerp_angle(
				mesh.global_rotation.y, angle_to_target, delta_factor * TURN_SENSITIVITY
			)

	var relative_motion_vec: Vector2 = Vector2(-movement.x, -movement.z).rotated(
		mesh.global_rotation.y
	)

	animation_tree["parameters/walk_space/blend_position"] = lerp(
		animation_tree["parameters/walk_space/blend_position"],
		relative_motion_vec,
		delta_factor * TURN_SENSITIVITY
	)

	super.physics_process(movement, delta)


func _on_nav_link_reached(details: Dictionary) -> void:
	if details["link_entry_position"].y <= details["link_exit_position"].y:
		# Going up or across -- need to jump
		jump()
	else:
		# Going down (just keep going!)
		pass


func _on_vision_cone_detected(body: Node3D) -> void:
	if body == target:
		target_detected = true
		print("target detected!")


func _on_vision_cone_lost_detection(body: Node3D) -> void:
	if body == target:
		target_detected = false
		print("target lost!")
