class_name CPPool
extends RefCounted

## CPPool - Tracks Crystal Points generated during a turn

# CP stored by element
var _cp: Dictionary = {}

func _init() -> void:
	clear()

## Clear all CP (called at end of each action)
func clear() -> void:
	for element in Enums.Element.values():
		_cp[element] = 0

## Add CP of a specific element
func add_cp(element: Enums.Element, amount: int) -> void:
	_cp[element] = _cp.get(element, 0) + amount

## Get CP of a specific element
func get_cp(element: Enums.Element) -> int:
	return _cp.get(element, 0)

## Get total CP available
func get_total_cp() -> int:
	var total = 0
	for element in _cp:
		total += _cp[element]
	return total

## Check if we can afford a card cost
func can_afford_card(card_data: CardDatabase.CardData) -> bool:
	if not card_data:
		return false

	var cost = card_data.cost
	var elements = card_data.elements

	# For Light/Dark cards, just need total CP
	var is_light_dark = false
	for element in elements:
		if Enums.is_light_or_dark(element):
			is_light_dark = true
			break

	if is_light_dark:
		return get_total_cp() >= cost

	# For multi-element cards, need at least 1 CP of each element
	if elements.size() > 1:
		for element in elements:
			if get_cp(element) < 1:
				return false
		# Total must be at least the cost
		return get_total_cp() >= cost

	# For single element cards, need at least 1 CP of that element
	var primary_element = elements[0] if elements.size() > 0 else Enums.Element.FIRE
	if get_cp(primary_element) < 1:
		return false

	return get_total_cp() >= cost

## Spend CP to pay a card cost
## Returns true if successful, false if cannot afford
func spend_for_card(card_data: CardDatabase.CardData) -> bool:
	if not can_afford_card(card_data):
		return false

	var cost = card_data.cost
	var elements = card_data.elements
	var remaining = cost

	# For multi-element, spend 1 of each required element first
	if elements.size() > 1:
		for element in elements:
			_cp[element] -= 1
			remaining -= 1

	# For single element (non-Light/Dark), spend at least 1 of that element
	elif elements.size() == 1:
		var element = elements[0]
		if not Enums.is_light_or_dark(element):
			_cp[element] -= 1
			remaining -= 1

	# Spend remaining from any element
	while remaining > 0:
		var spent = false
		for element in _cp:
			if _cp[element] > 0:
				_cp[element] -= 1
				remaining -= 1
				spent = true
				break
		if not spent:
			push_error("Failed to spend remaining CP")
			return false

	return true

## Check if we can afford an ability cost
func can_afford_ability(cost: CardDatabase.CostData) -> bool:
	if not cost:
		return true  # No cost means free

	# Check element-specific requirements
	if cost.fire > 0 and get_cp(Enums.Element.FIRE) < cost.fire:
		return false
	if cost.ice > 0 and get_cp(Enums.Element.ICE) < cost.ice:
		return false
	if cost.wind > 0 and get_cp(Enums.Element.WIND) < cost.wind:
		return false
	if cost.lightning > 0 and get_cp(Enums.Element.LIGHTNING) < cost.lightning:
		return false
	if cost.water > 0 and get_cp(Enums.Element.WATER) < cost.water:
		return false
	if cost.earth > 0 and get_cp(Enums.Element.EARTH) < cost.earth:
		return false
	if cost.light > 0 and get_cp(Enums.Element.LIGHT) < cost.light:
		return false
	if cost.dark > 0 and get_cp(Enums.Element.DARK) < cost.dark:
		return false

	# Check total
	return get_total_cp() >= cost.get_total_cp()

## Spend CP to pay an ability cost
func spend_for_ability(cost: CardDatabase.CostData) -> bool:
	if not can_afford_ability(cost):
		return false

	# Spend element-specific CP
	if cost.fire > 0:
		_cp[Enums.Element.FIRE] -= cost.fire
	if cost.ice > 0:
		_cp[Enums.Element.ICE] -= cost.ice
	if cost.wind > 0:
		_cp[Enums.Element.WIND] -= cost.wind
	if cost.lightning > 0:
		_cp[Enums.Element.LIGHTNING] -= cost.lightning
	if cost.water > 0:
		_cp[Enums.Element.WATER] -= cost.water
	if cost.earth > 0:
		_cp[Enums.Element.EARTH] -= cost.earth
	if cost.light > 0:
		_cp[Enums.Element.LIGHT] -= cost.light
	if cost.dark > 0:
		_cp[Enums.Element.DARK] -= cost.dark

	# Spend generic from any element
	var generic_remaining = cost.generic
	while generic_remaining > 0:
		for element in _cp:
			if _cp[element] > 0:
				_cp[element] -= 1
				generic_remaining -= 1
				break

	return true

## Get a display-friendly dictionary of current CP
func get_display_data() -> Dictionary:
	var data = {}
	for element in _cp:
		if _cp[element] > 0:
			data[Enums.element_to_string(element)] = _cp[element]
	return data

func _to_string() -> String:
	var parts = []
	for element in _cp:
		if _cp[element] > 0:
			parts.append("%s: %d" % [Enums.element_to_string(element), _cp[element]])
	if parts.size() == 0:
		return "[CPPool: empty]"
	return "[CPPool: " + ", ".join(parts) + "]"
