extends PathFollow3D
## Tower Defense — Lecture 26 (Final)
##
## Enemy that follows a Path3D, has health, and damages
## the player when reaching the end. Uses colored shapes
## for visualization.

# ============================================================
# SIGNALS
# ============================================================

signal reached_end(damage: int)
signal died(enemy_type: String)

# ============================================================
# ENEMY STATS (set based on type)
# ============================================================

const STATS := {
	"slime": {
		"hp": 30,
		"speed": 2.0,
		"damage": 10,
		"color": Color(0.2, 0.8, 0.2)  # Green
	},
	"goblin": {
		"hp": 50,
		"speed": 3.5,
		"damage": 15,
		"color": Color(0.8, 0.6, 0.2)  # Orange
	},
	"orc": {
		"hp": 100,
		"speed": 2.5,
		"damage": 25,
		"color": Color(0.8, 0.2, 0.2)  # Red
	}
}

# ============================================================
# STATE
# ============================================================

var enemy_type: String = "slime"
var max_hp: int = 30
var current_hp: int = 30
var speed: float = 2.0
var damage: int = 10
var enemy_color: Color = Color.GREEN

@onready var mesh_instance: MeshInstance3D = $MeshInstance3D
@onready var health_bar: MeshInstance3D = $HealthBar
@onready var health_bar_fill: MeshInstance3D = $HealthBar/Fill

# ============================================================
# LIFECYCLE
# ============================================================

func _ready() -> void:
	loop = false


func _process(delta: float) -> void:
	# Move along path
	progress += speed * delta
	
	# Check if reached end
	if progress_ratio >= 1.0:
		_reach_end()


## Initialize enemy with stats based on type
func initialize() -> void:
	if enemy_type not in STATS:
		enemy_type = "slime"
	
	var stats = STATS[enemy_type]
	max_hp = stats.hp
	current_hp = max_hp
	speed = stats.speed
	damage = stats.damage
	enemy_color = stats.color
	
	# Set mesh color
	var material := StandardMaterial3D.new()
	material.albedo_color = enemy_color
	mesh_instance.set_surface_override_material(0, material)
	
	_update_health_bar()


# ============================================================
# COMBAT
# ============================================================

## Take damage from tower
func take_damage(amount: int) -> void:
	current_hp -= amount
	current_hp = maxi(current_hp, 0)
	_update_health_bar()
	
	if current_hp <= 0:
		_die()


## Enemy dies
func _die() -> void:
	died.emit(enemy_type)
	queue_free()


## Enemy reaches end of path
func _reach_end() -> void:
	reached_end.emit(damage)
	queue_free()


# ============================================================
# HEALTH BAR
# ============================================================

func _update_health_bar() -> void:
	var health_percent := float(current_hp) / float(max_hp)
	health_bar_fill.scale.x = health_percent
	
	# Change color based on health
	var bar_color := Color.GREEN.lerp(Color.RED, 1.0 - health_percent)
	var material := StandardMaterial3D.new()
	material.albedo_color = bar_color
	health_bar_fill.set_surface_override_material(0, material)
