extends Control
@onready var map_size_label = $PanelContainer/VBoxContainer/MapSizeLabel
@onready var cell_count_label = $PanelContainer/VBoxContainer/CellCountLabel
@onready var loaded_cells_label = $PanelContainer/VBoxContainer/LoadedCellsLabel
@onready var loaded_ojects_label = $PanelContainer/VBoxContainer/LoadedTreesLabel

func _ready() -> void:
	update_cell_count()

func _process(_delta: float) -> void:
	update_map_size()
	update_loaded_cells_count()
	update_loaded_objects()

func update_map_size() -> void:
	var player_pos = %Player.position
	var cell_x = int(player_pos.x / 2.0)
	var cell_z = int(player_pos.z / 2.0)

	# Get biome data for current cell
	var biome_info = ""
	if Global.biome_data != null and not Global.biome_data.is_empty():
			# Check bounds to avoid errors
			var moisture_img = Global.biome_data.get("moisture")
			var temp_img = Global.biome_data.get("temperature")
			var elev_img = Global.biome_data.get("elevation")
			
			if moisture_img != null and temp_img != null and elev_img != null:
					# Make sure coordinates are within image bounds
					var img_width = moisture_img.get_width()
					var img_height = moisture_img.get_height()
					
					if cell_x >= 0 and cell_x < img_width and cell_z >= 0 and cell_z < img_height:
							var moisture = moisture_img.get_pixel(cell_x, cell_z).r
							var temperature = temp_img.get_pixel(cell_x, cell_z).r
							var elevation = elev_img.get_pixel(cell_x, cell_z).r
							
							biome_info = "\nMoisture: %.2f | Temp: %.2f | Elevation: %.2f" % [moisture, temperature, elevation]
					else:
							biome_info = "\nBiome: Out of bounds"
			else:
					biome_info = "\nBiome: Data not available"
	else:
			biome_info = "\nBiome: Not initialized"

	map_size_label.text = 'X: %.1f, Z: %.1f | Cell: (%d, %d)%s' % [player_pos.x, player_pos.z, cell_x, cell_z, biome_info]

func update_cell_count() -> void:
	cell_count_label.text = 'Cell Count: ' + str(Global.map_height * Global.map_width)

func update_loaded_cells_count() -> void:
	var actual_tiles = count_actual_tiles_in_scene()
	loaded_cells_label.text = 'Loaded chunks: ' + str(%TileGround.loaded_chunks.size()) + '\nActual tiles: ' + str(actual_tiles)

func update_loaded_objects() -> void:
	var debug_text = get_object_debug_text()
	loaded_ojects_label.text = debug_text

func count_actual_tiles_in_scene() -> int:
	var count = 0
	var tile_ground = %TileGround
	
	for child in tile_ground.get_children():
		if child.name.begins_with("Chunk_"):
			count += child.get_child_count()
	
	return count

func get_object_debug_text() -> String:
	var text = ""
	
	var total_objects = Performance.get_monitor(Performance.OBJECT_COUNT)
	var node_count = Performance.get_monitor(Performance.OBJECT_NODE_COUNT)
	var resource_count = Performance.get_monitor(Performance.OBJECT_RESOURCE_COUNT)
	var orphan_count = Performance.get_monitor(Performance.OBJECT_ORPHAN_NODE_COUNT)
	
	text += "Total Objects: " + str(total_objects) + "\n"
	text += "Nodes: " + str(node_count) + "\n"
	text += "Resources: " + str(resource_count) + "\n"
	text += "Orphans: " + str(orphan_count) + "\n"
	
	var scene_nodes = _count_all_nodes(get_tree().root)
	var leaked_nodes = node_count - scene_nodes # Better calculation
	var other_objects = total_objects - node_count - resource_count
	
	text += "Scene Tree: " + str(scene_nodes) + "\n"
	text += "Leaked Nodes: " + str(leaked_nodes) + "\n" # More accurate
	text += "Other Objects: " + str(other_objects) + "\n" # Show what else exists
	
	# Memory usage
	var static_mem = Performance.get_monitor(Performance.MEMORY_STATIC)
	var static_max = Performance.get_monitor(Performance.MEMORY_STATIC_MAX)
	
	text += "Static Mem: " + format_bytes(static_mem) + "\n"
	text += "Peak Mem: " + format_bytes(static_max) + "\n"

	text += "Trees: " + str(get_tree().get_nodes_in_group("tree").size())
	
	return text

func _count_all_nodes(node: Node) -> int:
	var count = 1
	for child in node.get_children():
		count += _count_all_nodes(child)
	return count

func format_bytes(bytes: float) -> String:
	if bytes < 1024:
		return str(int(bytes)) + "B"
	elif bytes < 1024 * 1024:
		return str(int(bytes / 1024)) + "KB"
	else:
		return str(int(bytes / (1024 * 1024))) + "MB"
