extends StaticBody3D
class_name Tower

var bullet : PackedScene = preload("res://Bullets/arrow.tscn")
@export var tower_name : String = "Pierre"
@export var bullet_damage : int = 1
@export var price : int = 100

@export_group("Energy")
@export var max_energy : float = 100.0 #Next thing to do
@export var energy_regen : float = 10.0
@export var energy_cost : float = 50.0
@onready var energy_bar : EnergyBar3D = $EnergyBar3D

var tower_button : TowerButton = null

var energy : float = max_energy:
	set(value):
		energy = clampf(value, 0.0, max_energy)
		energy_bar.update(value)
		if energy < energy_cost:
			is_exhausted = true
		else:
			is_exhausted = false

var current_targets : Array = []
var current : CharacterBody3D
var can_shoot : bool = true
var is_exhausted : bool = false

var is_rest : bool = false:
	set(value):
		is_rest = value
		if value:
			resting()
		else:
			in_action()


func _ready() -> void:
	energy_bar.set_up(energy, max_energy)

func _process(delta: float) -> void:
	if is_rest:
		return
	
	if is_instance_valid(current):
		if can_shoot && not is_exhausted:
			shoot()
			can_shoot = false
			$Cooldown.start()
	else:
		for i in $BulletContainer.get_child_count():
			$BulletContainer.get_child(i).queue_free()


func shoot() -> void:
	energy -= energy_cost
	
	var temp_bullet : Bullet = bullet.instantiate()
	temp_bullet.target = current
	temp_bullet.bullet_damage = bullet_damage
	$BulletContainer.add_child(temp_bullet)
	temp_bullet.global_position = $Aim.global_position


func resting() -> void:
	energy += energy_regen
	visible = false
	$EnergyCooldown.start()


func in_action() -> void:
	visible = true
	$EnergyCooldown.stop()


func choose_target(_current_targets : Array) -> void:
	var temp_array : Array = _current_targets
	var current_target : CharacterBody3D = null
	for i in temp_array:
		if current_target == null :
			current_target = i
		else:
			if i.get_parent().get_progress() > current_target.get_parent().get_progress():
				current_target = i
		
		current = current_target


func _on_range_body_entered(body: Node3D) -> void:
	if body is Enemy:
		current_targets.append(body)
		choose_target(current_targets)


func _on_range_body_exited(body: Node3D) -> void:
	if body is Enemy:
		current_targets.erase(body)
		choose_target(current_targets)


func _on_cooldown_timeout() -> void:
	can_shoot = true


func _on_energy_cooldown_timeout() -> void:
	resting()
