extends Node

# Signals
signal item_acquired(item_id: String)
signal item_removed(item_id: String)
signal inventory_changed
signal combination_attempted(item_a_id: String, item_b_id: String)

# State
var inventory: Array[String] = []
var obtained_items: Dictionary = {}
var stripped_items: Array[String] = []
var selected_item: String = ""

# Item definitions registry
var _item_definitions: Dictionary = {}


# -- Queries --

func has_item(item_id: String) -> bool:
	return inventory.has(item_id)

func has_obtained(item_id: String) -> bool:
	return obtained_items.has(item_id)

func has_any_of(item_ids: Array[String]) -> bool:
	if item_ids.is_empty():
		return false
	for item_id in item_ids:
		if has_item(item_id):
			return true
	return false

func has_obtained_any_of(item_ids: Array[String]) -> bool:
	if item_ids.is_empty():
		return false
	for item_id in item_ids:
		if has_obtained(item_id):
			return true
	return false

func has_obtained_all_of(item_ids: Array[String]) -> bool:
	if item_ids.is_empty():
		return true
	for item_id in item_ids:
		if not has_obtained(item_id):
			return false
	return true


# -- Mutations --

func acquire_item(item_id: String) -> void:
	inventory.append(item_id)
	obtained_items[item_id] = true
	item_acquired.emit(item_id)
	inventory_changed.emit()

func remove_item(item_id: String, quiet: bool = false) -> void:
	var idx = inventory.find(item_id)
	if idx == -1:
		return
	inventory.remove_at(idx)
	if not quiet:
		item_removed.emit(item_id)
	inventory_changed.emit()

func bulk_strip_items(event_items: Array[String], exempt_items: Array[String] = []) -> void:
	var remaining: Array[String] = []
	for item_id in inventory:
		if event_items.has(item_id) and not exempt_items.has(item_id):
			stripped_items.append(item_id)
		else:
			remaining.append(item_id)
	inventory = remaining
	inventory_changed.emit()


# -- Items --

func register_item(item_def: ItemDefinition) -> void:
	_item_definitions[item_def.id] = item_def

func get_item_definition(item_id: String) -> ItemDefinition:
	return _item_definitions.get(item_id, null)


# -- Combinations --

func attempt_combine(item_a_id: String, item_b_id: String) -> void:
	combination_attempted.emit(item_a_id, item_b_id)


# -- Selection --

func select_item(item_id: String) -> void:
	selected_item = item_id

func clear_selection() -> void:
	selected_item = ""
