extends Node2D

signal deal_damage(amount:int)
signal health_changed(old_value, new_value)
signal stamina_changed(old_value, new_value)
signal actions_done

@onready var _animation_player = $AnimationPlayer
@onready var _animation_sprite = $Sprite2D
@onready var _animation_damage_label = $DamageLabel

@export
var orientation:int = 1
@export
var health:int = 100
@export
var stamina:int = 100
@export
var descriptor:String = "Foo"

var _material_counter = 0

var _actions = []
var _action_queue = []
var _health = 0
var _stamina = 0

# Public methods
func init(actions):
	_actions = actions.duplicate(true)
	_health = health
	_stamina = stamina
	health_changed.emit(_health, _health)
	stamina_changed.emit(_stamina, _stamina)

func is_animation_idle() -> bool:
	return !_animation_player.is_playing() && _action_queue.is_empty()

func is_animation_done() -> bool:
	return is_animation_idle() && _actions.is_empty()

# Called when the node enters the scene tree for the first time.
func _ready():
	_animation_sprite.material.set_shader_parameter("aura_width", 0)
	_animation_sprite.flip_h = orientation
	_animation_player.play("RESET")

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
	pass

func _take_damage(amount : int):
	var old_health = _health
	_health -= amount
	if _animation_player.is_playing():
		print_debug("%s -> %s: _take_damage -> skip current animation %s!" % [Time.get_ticks_msec(), descriptor,_animation_player.current_animation])
		_animation_player.stop()

	print_debug("%s -> %s: _take_damage -> play HIT animation!" % [Time.get_ticks_msec(), descriptor])
	_animation_player.play("Hit")
	_animation_damage_label.show_damage(amount)

	health_changed.emit(old_health, _health)

func _alter_stamina(amount : int):
	if _stamina <= stamina:
		var old_stamina = _stamina
		_stamina = min(stamina, _stamina + amount)
		stamina_changed.emit(old_stamina, _stamina)

func _on_next_round():
	print_debug("%s -> %s: _on_next_round" % [Time.get_ticks_msec(), descriptor])
	if !_actions.is_empty():
		_alter_stamina(5)
		_action_queue = _actions.pop_front()
		_schedule_next_action()

	_material_counter -= 1
	if _material_counter == 0:
		_animation_sprite.material.set_shader_parameter("aura_width", 0)

func _schedule_next_action():
	if _animation_player.is_playing():
		return

	if _action_queue.is_empty():
		_animation_sprite.frame = 0
		actions_done.emit()
		return

	var action : String = _action_queue.pop_front()
	_animation_player.play(action)
	print_debug("%s -> %s: _schedule_next_action -> plays %s!" % [Time.get_ticks_msec(), descriptor, action])

	if action.begins_with("Attack1"):
		deal_damage.emit(5)
		_alter_stamina(-10)
	elif action.begins_with("Attack2"):
		deal_damage.emit(15)
		_alter_stamina(-20)


func _on_animation_finished(anim_name):
	print_debug("%s -> %s: _on_animation_finished -> %s!" % [Time.get_ticks_msec(), descriptor, anim_name])
	_schedule_next_action()
	
	if (anim_name == "PowerUp"):
		_animation_sprite.frame = 0
		_animation_sprite.material.set_shader_parameter("aura_width", 1)
		_material_counter = 3

func _on_animation_started(anim_name):
	print_debug("%s -> %s: _on_animation_started -> %s!" % [Time.get_ticks_msec(), descriptor, anim_name])
