class_name PlayableCharacter
extends CharacterBody2D

@export var health = 100
@export var speed = 100
@export var KNOCKBACK_POWER = 40
@export var KNOCKBACK_RANDOMNESS = 50
var last_dpad: Array[Vector2] = [Vector2.ZERO,Vector2.ZERO]
const FACING_ANGLE_EPSILON = 15

var can_move = true

@onready var animation_playback: AnimationNodeStateMachinePlayback = $AnimationTree.get("parameters/playback")

signal attack_did_hit(other: Area2D, power: int, attack_direction: Vector2)
signal defeated

func _unhandled_input(event): 
	if event.is_action_pressed("melee") and can_move:
		var animation_rng = randf_range(0, 1)
		$AnimationTree.set("parameters/melee/blend_position", animation_rng)
		$AnimationTree.set("parameters/conditions/melee", true)
		can_move = false
		velocity = Vector2.ZERO
		
func _physics_process(_delta):
	get_input()
	move_and_slide()
	
func set_animation_direction(direction: Vector2):
	$AnimationTree.set("parameters/idle/blend_position", direction)
	$AnimationTree.set("parameters/walk/blend_position", direction)
	$AnimationTree.set("parameters/melee/0/blend_position", direction)
	$AnimationTree.set("parameters/melee/1/blend_position", direction)
	$AnimationTree.set("parameters/melee/2/blend_position", direction)
	$AnimationTree.set("parameters/hurt/blend_position", direction)
	
func xor(a:bool, b:bool):
	return a != b

func get_input():
	var vertical = Input.get_axis("up", "down")
	var horizontal = Input.get_axis("left", "right")
	var input_direction = Vector2(horizontal, vertical)
	var input_angle = rad_to_deg(atan2(vertical,horizontal))
	
	var test = xor(abs(input_direction.dot(Vector2.RIGHT)) > 0.5, abs(input_direction.dot(Vector2.UP)) > 0.5)
	
	# Keep lateral directions when moving diagonally
	# if the player moves in one direction and then diagonally
	# (i.e. first left then up-left)
	if test or input_direction == Vector2.ZERO:
		last_dpad[1] = last_dpad[0]
		last_dpad[0] = input_direction
	if last_dpad[0] == Vector2.ZERO and input_direction != Vector2.ZERO:
		last_dpad[0] = input_direction
		
	if not can_move:
		input_direction = Vector2.ZERO
		last_dpad[0] = Vector2.ZERO
		last_dpad[1] = Vector2.ZERO	
	else:
		velocity = input_direction * speed

	if input_direction == Vector2.ZERO:
		$AnimationTree.set("parameters/conditions/is_moving", false)
	else:
		$AnimationTree.set("parameters/conditions/is_moving", true)
		set_animation_direction(last_dpad[0])


func _on_attackbox_area_entered(area: Area2D):
	var attack_vector: Vector2 = $AnimationTree.get("parameters/melee/0/blend_position")
	attack_did_hit.emit(area, 15, attack_vector)


func _on_hiro_dummy_defeated():
	print("Yaaaaay!!")


func _on_enemy_attack_did_hit(other, power, attack_direction):
	if other.get_parent().get_instance_id() == get_instance_id() :
		$Attackbox/Collider.set_deferred("disabled", true)
		health = health - power
		can_move = false
		if health <= 0:
			if Globals.nsfw:
				animation_playback.travel("nsfw_defeated_start")
			else:
				animation_playback.travel("defeated")
			defeated.emit()
			velocity = Vector2.ZERO
		else:
			var facing_direction = attack_direction * -1.0
			set_animation_direction(facing_direction)
			var knockback_direction = attack_direction.rotated(deg_to_rad(randf_range(-1, 1) * KNOCKBACK_RANDOMNESS))
			velocity = KNOCKBACK_POWER * knockback_direction.normalized()
			animation_playback.travel("hurt")
			$AnimationTree.set("parameters/conditions/melee", false)

func _on_animation_tree_animation_finished(anim_name):
	if anim_name.contains("hurt") or anim_name.contains("kick") or anim_name.contains("punch"):
		can_move = true
		$AnimationTree.set("parameters/conditions/melee", false)
	if anim_name.contains("kick") or anim_name.contains("punch"):
		$Attackbox/Collider.set_deferred("disabled", true)
