class_name PlayerInventory
extends Resource


@export var max_weight := 100
@export var items: Array[Item]


# calculating it every time is less bug-prone than keeping track of it
func total_weight() -> int:
	return items.reduce(_item_weight_sum, 0)


func add_item(new_item: Item) -> bool:
	# can't carry this
	# TODO: overburdening instead of this
	if (total_weight() + new_item.weight) > max_weight:
		return false
	
	# stacking is done purely automatically for now
	var items_like_this: Array[Item] = items.filter(_filter_same_items.bind(new_item))
	items_like_this.sort_custom(_sort_amount_descending)
	
	var stacked := false
	for item in items_like_this:
		if not item.stackable or item.amount == item.stack_size:
			continue
		item.amount += 1
		stacked = true
		break
	if not stacked:
		items.push_back(new_item)
	
	return true


func remove_item(item: Item) -> void:
	var items_like_this: Array[Item] = items.filter(_filter_same_items.bind(item))
	var items_sorted: Array[Item] = items_like_this.duplicate()
	items_sorted.sort_custom(_sort_amount_ascending)
	var least := items_sorted[0]
	
	if not least.stackable or least.amount == 1:
		items.erase(least)
	else:
		least.amount -= 1


func _sort_amount_ascending(a: Item, b: Item) -> bool:
	return a.amount < b.amount


func _sort_amount_descending(a: Item, b: Item) -> bool:
	return a.amount > b.amount


func _item_weight_sum(accum: int, item: Item) -> int:
	return accum + item.weight


func _filter_same_items(item: Item, original: Item) -> bool:
	return item.id == original.id
