## PlayerStats — 玩家属性统计（Autoload: PlayerStats）
## 权威来源：development_plan.md S2、numerical_design.md §1.2
extends Node

signal stats_changed
signal leveled_up(new_level: int)

# ── HP ───────────────────────────────────────────────
var hp:     float = 100.0
var hp_max: float = 100.0

# ── 资源 ──────────────────────────────────────────────
var gold:   int   = 0
var xp:     int   = 0

# ── 等级 ──────────────────────────────────────────────
var level:     int = 1
var xp_to_next: int = 10  # 升级所需 XP

# ── 战斗属性 ───────────────────────────────────────────
var cpu_limit:     int = 5    # 控制 MAX_OPS = cpu_limit * 40
var armor:         float = 0.0
var resistance:    float = 0.0  # 0.0~1.0

# ── 魔力（MVP）─────────────────────────────────────────
var mana:       float = 100.0
var mana_max:   float = 100.0
var mana_regen: float = 5.0    # 每秒回复
var mana_heat:  float = 0.0    # 递增蓝耗热值（0=无，1=蓝耗翻倍）
var mana_leech: float = 0.0    # 击杀回蓝量（换杖/换牌重算）

func _ready() -> void:
	EventBus.subscribe(EventID.PLAYER_DAMAGED, _on_player_damaged)
	EventBus.subscribe(EventID.ENEMY_KILLED, _on_enemy_killed)

func _on_enemy_killed(_payload: Dictionary) -> void:
	gain_mana(mana_leech)

## 升级曲线：roundf(10 × 1.4^(level-1))，P6-N16
## Level 1→2: 10 XP; Level 5→6: ≈ 54 XP
static func xp_for_level(lv: int) -> int:
	return roundi(10.0 * pow(1.4, float(lv - 1)))

func gain_xp(amount: int) -> void:
	xp += amount
	while xp >= xp_to_next:
		xp -= xp_to_next
		level += 1
		xp_to_next = xp_for_level(level)
		leveled_up.emit(level)
		EventBus.emit(EventID.LEVEL_UP, {"level": level})
	stats_changed.emit()

func gain_gold(amount: int) -> void:
	gold += amount
	stats_changed.emit()

func spend_gold(amount: int) -> bool:
	if gold < amount:
		return false
	gold -= amount
	stats_changed.emit()
	return true

func take_damage(amount: float) -> void:
	hp = max(0.0, hp - amount * SettingsManager.player_dmg_taken_mult())  # 难度减伤（初学者×0.7）
	stats_changed.emit()
	if hp <= 0.0:
		EventBus.emit(EventID.PLAYER_DIED, {})

func heal(amount: float) -> void:
	hp = min(hp_max, hp + amount)
	stats_changed.emit()

func get_hp_percent() -> float:
	return hp / max(hp_max, 0.001)

## 换杖时设定蓝池上限/回速，并把当前蓝夹到 [0, max]
func set_mana_pool(max_v: float, regen: float) -> void:
	mana_max   = max_v
	mana_regen = regen
	mana       = clampf(mana, 0.0, mana_max)
	stats_changed.emit()

## 花费魔力；够则扣除返回 true，否则不变返回 false
func spend_mana(cost: float) -> bool:
	if mana < cost:
		return false
	mana -= cost
	stats_changed.emit()
	return true

## 每帧回蓝（PlayerManager 驱动）。不 emit stats_changed —— HUD 每帧直接读 mana，
## 避免回蓝过程每帧发信号触发商店刷新。
func regen_mana(delta: float) -> void:
	if mana >= mana_max:
		return
	mana = min(mana_max, mana + mana_regen * delta)

## 击杀回蓝（魔力虹吸）
func gain_mana(n: float) -> void:
	if n <= 0.0:
		return
	mana = min(mana_max, mana + n)
	stats_changed.emit()

## 主动 HP 代价（infinite_spells / heavy_cost）——直接扣血，不走难度减伤
func spend_hp_cost(amount: float) -> void:
	if amount <= 0.0:
		return
	hp = max(0.0, hp - amount)
	stats_changed.emit()
	if hp <= 0.0:
		EventBus.emit(EventID.PLAYER_DIED, {})

func _on_player_damaged(payload: Dictionary) -> void:
	take_damage(float(payload.get("damage", 0.0)))

func reset_for_run() -> void:
	hp        = hp_max
	mana      = mana_max
	gold      = 0
	xp        = 0
	level     = 1
	xp_to_next = xp_for_level(1)
	stats_changed.emit()

func get_save_data() -> Dictionary:
	return {"hp": hp, "hp_max": hp_max, "gold": gold, "xp": xp, "level": level, "cpu_limit": cpu_limit}

func load_save_data(data: Dictionary) -> void:
	hp        = float(data.get("hp",     100.0))
	hp_max    = float(data.get("hp_max", 100.0))
	gold      = int(data.get("gold",    0))
	xp        = int(data.get("xp",      0))
	level     = int(data.get("level",   1))
	cpu_limit = int(data.get("cpu_limit", 5))
	xp_to_next = xp_for_level(level)
	stats_changed.emit()
