extends Node

#const GOLD_CURRENCY_ID: StringName = &"gold"
#const GEMS_CURRENCY_ID: StringName = &"gems"
#const LEGACY_CURRENCY_INDEX_TO_ID: Dictionary = {
	#0: GOLD_CURRENCY_ID,
	#1: GEMS_CURRENCY_ID,
#}

const CURRENCY_DIRECTORY_PATH: String = "res://docs/gyms/currencies"
const CURRENCY_RESOURCE_EXTENSIONS: PackedStringArray = ["tres", "res"]

var _currency_by_id: Dictionary = {}
var _catalog_initialized: bool = false

func _ready() -> void:
	_initialize_currency_catalog()

func get_known_currencies() -> Array[Currency]:
	_initialize_currency_catalog_if_needed()

	var result: Array[Currency] = []
	for raw_currency in _currency_by_id.values():
		var currency: Currency = raw_currency as Currency
		if currency != null:
			result.append(currency)
	return result

func get_known_currency_ids() -> Array[StringName]:
	_initialize_currency_catalog_if_needed()

	var ids: Array[StringName] = []
	for raw_currency_id in _currency_by_id.keys():
		var currency_id: StringName = _normalize_currency_id(StringName(String(raw_currency_id)))
		if currency_id == &"":
			continue
		ids.append(currency_id)
	return ids

func get_currency_id(currency: Currency) -> StringName:
	if currency == null:
		return &""

	var raw_id: Variant = currency.id
	if raw_id is StringName:
		return _normalize_currency_id(raw_id)
	return _normalize_currency_id(StringName(String(raw_id)))

func parse_currency_id(raw_currency: Variant) -> StringName:
	#if raw_currency is int:
		#return currency_id_from_legacy_index(raw_currency)

	var currency_text: String = String(raw_currency).to_lower().strip_edges()
	if currency_text == "gem":
		currency_text = "gems"
	return _normalize_currency_id(StringName(currency_text))

#func currency_id_from_legacy_index(currency_index: int) -> StringName:
	#return LEGACY_CURRENCY_INDEX_TO_ID.get(currency_index, &"")

func is_known_currency_id(currency_id: StringName) -> bool:
	_initialize_currency_catalog_if_needed()

	var normalized_currency_id: StringName = _normalize_currency_id(currency_id)
	if normalized_currency_id == &"":
		return false
	return _currency_by_id.has(normalized_currency_id)

func get_currency_resource(currency_id: StringName) -> Currency:
	_initialize_currency_catalog_if_needed()

	var normalized_currency_id: StringName = _normalize_currency_id(currency_id)
	if normalized_currency_id == &"":
		return null

	var raw_currency: Variant = _currency_by_id.get(normalized_currency_id)
	if raw_currency is Currency:
		return raw_currency
	return null

func get_currency_name(currency_id: StringName) -> String:
	var currency: Currency = get_currency_resource(currency_id)
	if currency != null:
		var display_name: String = String(currency.display_name).strip_edges()
		if not display_name.is_empty():
			return display_name
	return _humanize_currency_id(currency_id)

func get_currency_icon(currency_id: StringName) -> Texture2D:
	var currency: Resource = get_currency_resource(currency_id)
	if currency == null:
		return null

	var raw_icon: Variant = currency.icon
	if raw_icon is Texture2D:
		return raw_icon
	return null

func _initialize_currency_catalog_if_needed() -> void:
	if _catalog_initialized:
		return
	_initialize_currency_catalog()

func _initialize_currency_catalog() -> void:
	_currency_by_id.clear()
	_catalog_initialized = true

	var currency_resource_paths: PackedStringArray = _discover_currency_resource_paths()
	for resource_path in currency_resource_paths:
		var loaded_resource: Resource = load(resource_path)
		if loaded_resource == null:
			push_warning("Failed to load currency resource at '%s'." % resource_path)
			continue
		if not (loaded_resource is Currency):
			continue

		var currency_id: StringName = get_currency_id(loaded_resource)
		if currency_id == &"":
			push_warning("Skipping currency with missing id: %s" % resource_path)
			continue
		if _currency_by_id.has(currency_id):
			push_warning("Duplicate currency id '%s' found at %s. Keeping first occurrence." % [String(currency_id), resource_path])
			continue

		_currency_by_id[currency_id] = loaded_resource

	if _currency_by_id.is_empty():
		push_warning("No currency resources discovered under %s. Ensure currency .tres files exist and are included in export presets." % CURRENCY_DIRECTORY_PATH)

func _discover_currency_resource_paths() -> PackedStringArray:
	var result: PackedStringArray = []
	var directory: DirAccess = DirAccess.open(CURRENCY_DIRECTORY_PATH)
	if directory == null:
		push_warning("Unable to open currency directory: %s" % CURRENCY_DIRECTORY_PATH)
		return result

	directory.list_dir_begin()
	var entry_name: String = directory.get_next()
	while not entry_name.is_empty():
		if directory.current_is_dir() or entry_name.begins_with("."):
			entry_name = directory.get_next()
			continue

		var extension: String = entry_name.get_extension().to_lower()
		if CURRENCY_RESOURCE_EXTENSIONS.has(extension):
			result.append("%s/%s" % [CURRENCY_DIRECTORY_PATH, entry_name])

		entry_name = directory.get_next()
	directory.list_dir_end()

	result.sort()
	return result

func _normalize_currency_id(currency_id: StringName) -> StringName:
	var normalized: String = String(currency_id).to_lower().strip_edges()
	if normalized.is_empty():
		return &""
	return StringName(normalized)

func _humanize_currency_id(currency_id: StringName) -> String:
	var normalized: String = String(_normalize_currency_id(currency_id))
	if normalized.is_empty():
		return "Unknown"
	return normalized.replace("_", " ").capitalize()
