class_name CharacterStats extends Resource

signal level_up_notification()
signal update_stats()

class Ability:
	var min_modifier: float
	var max_modifier: float
	# Scales between 0-100, 0 being the worst, 100 the best
	var score: int = 25:
		set(value):
			score = clamp(value, 0, 100)

	func _init(min_mod: float, max_mod: float) -> void:
		min_modifier = min_mod
		max_modifier = max_mod

	func percentile_lerp(min_bound: float, max_bound: float) -> float:
		return lerp(min_bound, max_bound, score / 100.0)

	func get_modifier() -> float:
		return percentile_lerp(min_modifier, max_modifier)

	func inc() -> void:
		score += randi_range(2, 5)

var level: int = 1
var xp: int = 0:
	set(value):
		xp = value
		var boundary: int = perc_level_up_boundary()
		while xp > boundary:
			xp -= boundary
			level_up()
			boundary = perc_level_up_boundary()
		update_stats.emit()

const MIN_DASH_COOLDOWN: float = 1.5
const MAX_DASH_COOLDOWN: float = 0.5

# Damage bonus on attack
var strength: Ability = Ability.new(2.0, 12.0)
# Movement speed meters/second
var speed: Ability = Ability.new(3.0, 7.0)
# HP bonus per level
var endurance: Ability = Ability.new(5.0, 25.0)
# Crit chance
var agility: Ability = Ability.new(0.05, 0.25)

func get_max_hp() -> float:
	return 20 + int(level * endurance.get_modifier())

func get_dash_cooldown() -> float:
	return agility.percentile_lerp(MIN_DASH_COOLDOWN, MAX_DASH_COOLDOWN)

func level_up() -> void:
	level += 1
	strength.inc()
	speed.inc()
	endurance.inc()
	agility.inc()
	level_up_notification.emit()

func perc_level_up_boundary() -> int:
	return int(50 * pow(1.2, level))

func cubic_level_up_boundary() -> int:
	return int(50 + pow(level, 3))

