class_name CombatSystem extends Node

func create_proposal(attacker: Unit, defender: Unit) -> CombatProposal:
	var proposal := CombatProposal.new()

	proposal.attacker = _snapshot(attacker, defender)
	proposal.defender = _snapshot(defender, attacker)

	return proposal

func _snapshot(unit: Unit, opponent: Unit) -> CombatProposal.CombatantStats:
	var stats := CombatProposal.CombatantStats.new()
	stats.unit = unit
	stats.max_hp = unit.current_stats.max_hp
	stats.hp = unit.current_stats.current_hp
	stats.sp = unit.current_stats.current_sp
	stats.hit = unit.current_stats.hit - opponent.current_stats.eva
	stats.atk = unit.current_stats.phys_atk
	stats.def = unit.current_stats.phys_def
	stats.spd = unit.current_stats.spd
	return stats

func process_combat(attacker: Unit, defender: Unit) -> void:
	if not attacker.is_alive() or not defender.is_alive():
		return
	var proposal := create_proposal(attacker, defender)
	var atk_name := attacker.current_info.name
	var def_name := defender.current_info.name
	print("=== Combat: %s vs %s ===" % [atk_name, def_name])
	print("  %s — HP:%d ATK:%d DEF:%d HIT:%d" % [atk_name, proposal.attacker.hp, proposal.attacker.atk, proposal.attacker.def, proposal.attacker.hit])
	print("  %s — HP:%d ATK:%d DEF:%d HIT:%d" % [def_name, proposal.defender.hp, proposal.defender.atk, proposal.defender.def, proposal.defender.hit])
	apply_proposal(proposal)
	var atk_hp := attacker.current_stats.current_hp if is_instance_valid(attacker) else 0
	var def_hp := defender.current_stats.current_hp if is_instance_valid(defender) else 0
	print("  Result: %s HP=%d, %s HP=%d" % [atk_name, atk_hp, def_name, def_hp])


func apply_proposal(proposal: CombatProposal) -> void:
	var atk_stats := proposal.attacker
	var def_stats := proposal.defender
	var atk_unit := atk_stats.unit
	var def_unit := def_stats.unit

	# Attacker strikes
	var atk_roll := randi_range(1, 100)
	if atk_roll <= atk_stats.hit:
		var damage := maxi(atk_stats.atk - def_stats.def, 0)
		def_unit.take_damage(damage)

	# Counterattack if defender survives
	if def_unit.is_alive():
		var def_roll := randi_range(1, 100)
		if def_roll <= def_stats.hit:
			var damage := maxi(def_stats.atk - atk_stats.def, 0)
			atk_unit.take_damage(damage)
