extends CanvasLayer

# Ingame HUD - Displays player health, level, time, and boss health

var label_life: Label = null
var texture_progress_bar_hp: TextureProgressBar = null
var label_keys: Label = null
var label_keys_value: Label = null
var label_level: Label = null
var label_level_value: Label = null
var label_time: Label = null
var label_time_value: Label = null
var label_boss: Label = null
var texture_progress_bar_boss_hp: TextureProgressBar = null

var game_world: Node = null
var local_player: Node = null
var level_start_time: float = 0.0
var player_search_attempts: int = 0
var max_player_search_attempts: int = 100  # Limit retries to prevent infinite recursion
var timer_running: bool = true  # Flag to stop/start timer

func _ready():
	print("IngameHUD: _ready() called")
	
	# Find nodes safely (using get_node_or_null to avoid crashes)
	label_life = get_node_or_null("UpperLeft/HBoxContainer/VBoxContainerLIFE/LabelLife")
	texture_progress_bar_hp = get_node_or_null("UpperLeft/HBoxContainer/VBoxContainerLIFE/TextureProgressBarHP")
	label_keys = get_node_or_null("UpperLeft/HBoxContainer/VBoxContainerKeys/LabelKeys")
	label_keys_value = get_node_or_null("UpperLeft/HBoxContainer/VBoxContainerKeys/HBoxContainer/LabelKeysValue")
	label_level = get_node_or_null("UpperLeft/HBoxContainer/VBoxContainerLevel/LabelLevel")
	label_level_value = get_node_or_null("UpperLeft/HBoxContainer/VBoxContainerLevel/LabelLevelValue")
	label_time = get_node_or_null("UpperLeft/HBoxContainer/VBoxContainerTime/LabelTime")
	label_time_value = get_node_or_null("UpperLeft/HBoxContainer/VBoxContainerTime/LabelTimeValue")
	label_boss = get_node_or_null("UpperRight/HBoxContainer/VBoxContainerBoss/LabelBoss")
	texture_progress_bar_boss_hp = get_node_or_null("UpperRight/HBoxContainer/VBoxContainerBoss/TextureProgressBarBossHP")
	
	# Debug: Check if nodes were found
	if not label_time_value:
		print("IngameHUD: ERROR - label_time_value not found!")
	else:
		print("IngameHUD: Nodes found successfully")
	
	# Ensure visibility
	visible = true
	layer = 100  # High layer to ensure HUD is on top
	
	# Find game world
	game_world = get_tree().get_first_node_in_group("game_world")
	if not game_world:
		print("IngameHUD: WARNING - game_world not found in group")
	
	# Initially hide boss health bar
	if texture_progress_bar_boss_hp:
		texture_progress_bar_boss_hp.visible = false
	if label_boss:
		label_boss.visible = false
	
	# Start level timer
	level_start_time = Time.get_ticks_msec() / 1000.0
	
	# Find local player (with retry limit)
	player_search_attempts = 0
	_find_local_player()

func _find_local_player():
	# Prevent infinite recursion
	player_search_attempts += 1
	if player_search_attempts > max_player_search_attempts:
		print("IngameHUD: Warning - Could not find local player after ", max_player_search_attempts, " attempts. HUD will continue without player data.")
		return
	
	# Find the local player (first player with authority)
	var players = get_tree().get_nodes_in_group("player")
	
	# Check if we're in multiplayer mode
	var is_multiplayer = multiplayer and multiplayer.has_multiplayer_peer()
	
	if is_multiplayer:
		# In multiplayer mode, find player with authority
		for player in players:
			if player.has_method("is_multiplayer_authority") and player.is_multiplayer_authority():
				local_player = player
				print("IngameHUD: Found local player")
				return
	else:
		# In single-player mode, use first player
		if players.size() > 0:
			local_player = players[0]
			print("IngameHUD: Found player (single-player mode)")
			return
	
	# If not found, try again later (but only if we haven't exceeded attempts)
	if not local_player and player_search_attempts <= max_player_search_attempts:
		call_deferred("_find_local_player")

func _process(_delta):
	# Only update if nodes exist
	if not label_time_value:
		return  # Nodes not initialized yet, skip updates
	
	# Update player health
	if local_player and is_instance_valid(local_player):
		_update_player_health()
		_update_keys_display()
	
	# Update level display
	_update_level_display()
	
	# Update time display
	_update_time_display()
	
	# Update boss health (if boss exists)
	_update_boss_health()

func _update_player_health():
	if not local_player or not texture_progress_bar_hp:
		return
	
	var health = 0
	var max_health = 100
	
	# Try to get health from character_stats first (property always exists in player.gd)
	if local_player.character_stats:
		health = local_player.character_stats.hp
		max_health = local_player.character_stats.maxhp
	else:
		# Fallback to direct properties (these are getters in player.gd, always available)
		health = local_player.current_health
		max_health = local_player.max_health
	
	# Update progress bar
	texture_progress_bar_hp.max_value = max_health
	texture_progress_bar_hp.value = health

func _update_keys_display():
	if not local_player or not label_keys_value:
		return
	
	# Get key count from player (keys property always exists in player.gd)
	var key_count = local_player.keys
	label_keys_value.text = str(key_count)

func _update_level_display():
	if not label_level_value:
		return
	
	# current_level is always defined in game_world.gd
	if game_world:
		var level = game_world.current_level
		label_level_value.text = str(level)

func _update_time_display():
	if not label_time_value:
		return
	
	# Only update if timer is running
	if not timer_running:
		return
	
	# Calculate elapsed time since level start
	var current_time = Time.get_ticks_msec() / 1000.0
	var elapsed_time = current_time - level_start_time
	
	# Format as MM:SS
	var minutes = int(elapsed_time / 60)
	var seconds = int(elapsed_time) % 60
	label_time_value.text = "%02d:%02d" % [minutes, seconds]

func get_level_time() -> float:
	# Get the current level time (even if timer is stopped)
	var current_time = Time.get_ticks_msec() / 1000.0
	return current_time - level_start_time

func stop_timer():
	# Stop the timer when level completes
	timer_running = false

func start_timer():
	# Start/reset the timer for new level
	timer_running = true
	level_start_time = Time.get_ticks_msec() / 1000.0

func _update_boss_health():
	# Find boss enemy (if any)
	var boss_enemy = null
	var enemies = get_tree().get_nodes_in_group("enemy")
	for enemy in enemies:
		# Check if enemy is a boss (could check metadata or name)
		if enemy.has_meta("is_boss") and enemy.get_meta("is_boss"):
			boss_enemy = enemy
			break
	
	if boss_enemy and is_instance_valid(boss_enemy):
		# Show boss health bar
		if texture_progress_bar_boss_hp:
			texture_progress_bar_boss_hp.visible = true
		if label_boss:
			label_boss.visible = true
		
		# Update boss health (properties are always defined in enemy_base.gd)
		var health = boss_enemy.current_health
		var max_health = boss_enemy.max_health
		
		if texture_progress_bar_boss_hp:
			texture_progress_bar_boss_hp.max_value = max_health
			texture_progress_bar_boss_hp.value = health
	else:
		# Hide boss health bar if no boss
		if texture_progress_bar_boss_hp:
			texture_progress_bar_boss_hp.visible = false
		if label_boss:
			label_boss.visible = false

func reset_level_timer():
	# Reset timer when starting a new level
	start_timer()
