extends Node2D

@export var speed = 100 # How fast the virus will move (pixels/sec).
@export var attack_range = 1000 # virus vision radius (pixels)
@export var max_health = 10

var health = max_health

# a virus is instantiated as Spawning and transitions (matures) into Spawned
# after a timer timeout, after which it is activated and ready to do its thing.
enum SpawningState {Spawning, Spawned}
# when idle, a virus Waits. if it has already performed some action, it may
# become Blocked for a while. otherwise it might be Running. like a process.
enum ActionState {Blocked, Waiting, Running}

var spawning_state
var action_state

var knockback_timer: Timer = Timer.new()
var knockback = Vector2.ZERO

# temp 0 because of if len == 0 in process
var targets = [0] # who the virus will attack

func _ready():
	self.spawning_state = SpawningState.Spawning
	self.action_state = ActionState.Waiting
	self.add_to_group("Virus")
	$AnimationTree.set("parameters/transition/transition_request", "processing")
	knockback_timer.one_shot = true
	add_child(knockback_timer);

func _process(delta):
	if self.spawning_state != SpawningState.Spawned:
		return # do nothing if not yet spawned
	if self.targets.size() == 0:
		return # do nothing if no set targets

	# --- determine nearest target
	var nearest_target = get_node("../../Player").position
	var shortest_distance = nearest_target.distance_to(self.position)
	
	# --- attack the nearest target, if within range
	if self.action_state != ActionState.Blocked:
		if shortest_distance < self.attack_range:
			self.attack(nearest_target)

	if knockback_timer.time_left > 0:
		print_debug("knockback timer left: %f %s" % [knockback_timer.time_left, knockback])
		self.position += knockback * delta
	else:
		# --- move towards nearest target
		self.position += \
			self.position.direction_to(nearest_target) * self.speed * delta

func attack(target):
	# do attack, block until timer
	self.action_state = ActionState.Blocked

func set_spawning():
	self.spawning_state = SpawningState.Spawning

func set_spawned():
	self.spawning_state = SpawningState.Spawned

func take_hit(damage, knockback_vector, knockback_strength = 1):
	$HitSFX.play();
	if self.spawning_state == SpawningState.Spawning:
		health -= damage * 2
	else:
		health -= damage
	if health <= 0:
		queue_free()
	elif knockback_strength > 0:
		knockback = -knockback_vector;
		knockback_timer.start(0.2 * knockback_strength);
		# Flash white?

func _on_body_entered(body: Node2D) -> void:
	if self.spawning_state == SpawningState.Spawning:
		return
	body.take_hit(1, self.position.direction_to(body.position) * 500, 2)
