class_name Inventory extends Resource

class InventoryIterator extends Iterator:
	var values: Array[ItemInstance]
	var size: int
	var index: int = 0

	@warning_ignore("shadowed_variable")
	func _init(values: Array[ItemInstance], size: int = values.size()) -> void:
		self.values = values
		self.size = size

	func next() -> Option:
		if index < size:
			var value = Option.some(values[index])
			index += 1
			return value
		else:
			return Option.none

@export var initial_items: Array[ItemInstance]
@export var max_capacity: int = 6

var items: Dictionary[int, ItemInstance]
var size: int:
	get: return items.size()

signal item_added(item: Item, quantity: int)
signal item_removed(item: Item, remaining: int)
signal updated

func _init():
	call_deferred("_ready")

func _ready():
	for item in initial_items:
		items[_get_id(item.item)] = item
	updated.emit()

func _get_id(item: Item) -> int:
	return item.get_instance_id()

func _item_eq(a: Item, b: ItemInstance) -> bool:
	return a.item == b

func has_item(item: Item) -> bool:
	return items.has(_get_id(item))

func find(item: Item) -> Option:
	match items.get(_get_id(item)):
		null: return Option.none
		var found: return Option.some(found)

func add_item(item: Item, quantity: int = 1):
	var id = _get_id(item)
	var inst = items.get_or_add(id)
	inst.quantity += quantity
	item_added.emit(item, inst.quantity)
	updated.emit()

func remove_item(item: Item, quantity: int = 1):
	if find(item):
		item.quantity -= quantity
		if item.quantity <= 0:
			items.erase(_get_id(item))
		item_removed.emit(item, item.quantity)
		updated.emit()

func iter() -> InventoryIterator:
	return InventoryIterator.new(items.values(), max_capacity)
