# HUD.gd
# Verwaltet die Spieler-UI: HP-Leiste, XP-Leiste, Aktionsleiste (Slots 1-9)
extends CanvasLayer

signal slot_clicked(slot_index: int)
signal slot_drag_removed(slot_index: int)
signal slot_drag_swapped(from_slot: int, to_slot: int)

# Drag & Drop State
var drag_active = false
var drag_highlight_slot = -1
var drag_from_slot = -1  # Slot von dem aus gedraggt wird
var drag_icon: TextureRect = null
var drag_item = null  # Das gedraggte Consumable

@onready var health_bar = $Control/HealthBar
@onready var health_label = $Control/HealthBar/HealthLabel

# Level/XP UI (wird dynamisch erstellt)
var level_label: Label
var xp_bar: ProgressBar
var gold_label: Label
@onready var action_slots = [
	$Control/ActionBar/A1,
	$Control/ActionBar/A2,
	$Control/ActionBar/A3,
	$Control/ActionBar/A4,
	$Control/ActionBar/A5,
	$Control/ActionBar/A6,
	$Control/ActionBar/A7,
	$Control/ActionBar/A8,
	$Control/ActionBar/A9
]

var active_slot = 0
var slot_icons = [] # TextureRect nodes für Icons
var slot_cooldown_overlays = [] # ColorRect für Cooldown-Anzeige
var slot_cooldown_labels = [] # Label für Cooldown-Text
var slot_stack_labels = [] # Label für Stack-Anzahl

# Ressourcen-Bar (Mana/Energie/Wut)
var resource_bar: ProgressBar
var resource_label: Label

# Castbar
var castbar: ProgressBar
var castbar_label: Label
var castbar_container: PanelContainer

func _ready():
	_create_level_ui()

	for i in range(9):
		# Icon erstellen — füllt den ganzen Slot
		var icon = TextureRect.new()
		icon.name = "Icon"
		icon.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
		icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
		icon.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
		icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
		action_slots[i].add_child(icon)
		slot_icons.append(icon)

		# Slot-Nummer (oben links, über dem Icon)
		var slot_number = Label.new()
		slot_number.name = "SlotNumber"
		slot_number.text = str(i + 1)
		slot_number.position = Vector2(2, 0)
		slot_number.size = Vector2(20, 16)
		slot_number.add_theme_font_size_override("font_size", 11)
		slot_number.add_theme_color_override("font_color", Color(1, 1, 1, 0.9))
		slot_number.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 1))
		slot_number.add_theme_constant_override("shadow_offset_x", 1)
		slot_number.add_theme_constant_override("shadow_offset_y", 1)
		slot_number.mouse_filter = Control.MOUSE_FILTER_IGNORE
		action_slots[i].add_child(slot_number)

		# Cooldown-Overlay erstellen (dunkle Überlagerung)
		var cooldown_overlay = ColorRect.new()
		cooldown_overlay.name = "CooldownOverlay"
		cooldown_overlay.color = Color(0, 0, 0, 0.7)
		cooldown_overlay.size = Vector2(50, 50)
		cooldown_overlay.position = Vector2(0, 0)
		cooldown_overlay.visible = false
		cooldown_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE
		action_slots[i].add_child(cooldown_overlay)
		slot_cooldown_overlays.append(cooldown_overlay)

		# Cooldown-Text erstellen
		var cooldown_label = Label.new()
		cooldown_label.name = "CooldownLabel"
		cooldown_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
		cooldown_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
		cooldown_label.size = Vector2(50, 50)
		cooldown_label.position = Vector2(0, 0)
		cooldown_label.add_theme_font_size_override("font_size", 16)
		cooldown_label.visible = false
		cooldown_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
		action_slots[i].add_child(cooldown_label)
		slot_cooldown_labels.append(cooldown_label)

		# Stack-Count Label (unten rechts)
		var stack_label = Label.new()
		stack_label.name = "StackLabel"
		stack_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
		stack_label.vertical_alignment = VERTICAL_ALIGNMENT_BOTTOM
		stack_label.size = Vector2(50, 50)
		stack_label.position = Vector2(-4, -2)
		stack_label.add_theme_font_size_override("font_size", 11)
		stack_label.visible = false
		stack_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
		action_slots[i].add_child(stack_label)
		slot_stack_labels.append(stack_label)

		# Button für Klicks und Drag erstellen
		var button = Button.new()
		button.name = "SlotButton"
		button.flat = true
		button.size = Vector2(50, 50)
		button.position = Vector2(0, 0)
		button.modulate = Color(1, 1, 1, 0) # Unsichtbar
		var slot_index = i
		button.pressed.connect(func(): _on_slot_clicked(slot_index))
		button.button_down.connect(func(): _on_slot_drag_start(slot_index))
		action_slots[i].add_child(button)

# Drag aus Aktionsleiste starten
func _on_slot_drag_start(slot_index: int):
	# Prüfe ob ein Consumable im Slot liegt (wird vom Player gesetzt)
	# Signal an Player senden um Item abzufragen
	_start_actionbar_drag(slot_index)

func _start_actionbar_drag(slot_index: int):
	drag_from_slot = slot_index
	drag_active = true
	# Icon am Cursor erstellen aus dem aktuellen Slot-Icon
	var current_texture = slot_icons[slot_index].texture
	if current_texture == null:
		drag_active = false
		drag_from_slot = -1
		return
	drag_icon = TextureRect.new()
	drag_icon.texture = current_texture
	drag_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
	drag_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
	drag_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
	var drag_layer = CanvasLayer.new()
	drag_layer.name = "DragLayer"
	drag_layer.layer = 200
	drag_layer.add_child(drag_icon)
	get_tree().root.add_child(drag_layer)
	# Größe erst nach add_child setzen
	drag_icon.custom_minimum_size = Vector2(48, 48)
	drag_icon.size = Vector2(48, 48)
	drag_icon.position = get_viewport().get_mouse_position() - Vector2(24, 24)

func _process(_delta):
	if drag_from_slot >= 0 and drag_icon:
		drag_icon.position = get_viewport().get_mouse_position() - Vector2(20, 20)
		update_drag_hover(get_viewport().get_mouse_position())

func _input(event):
	if not drag_active or drag_from_slot < 0:
		return
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
		_end_actionbar_drag()

func _end_actionbar_drag():
	var drop_slot = get_slot_at_position(get_viewport().get_mouse_position())
	if drop_slot >= 0 and drop_slot <= 8 and drop_slot != drag_from_slot:
		# Auf anderen Slot verschoben -> swap
		slot_drag_swapped.emit(drag_from_slot, drop_slot)
	elif drop_slot < 0 or drop_slot > 8:
		# Außerhalb gedroppt -> aus Leiste entfernen
		slot_drag_removed.emit(drag_from_slot)
	# Aufräumen
	_clear_drag_highlight()
	if drag_icon:
		var drag_layer = drag_icon.get_parent()
		drag_layer.queue_free()
		drag_icon = null
	drag_active = false
	drag_from_slot = -1

# Slot-Klick Handler
func _on_slot_clicked(slot_index: int):
	if drag_active:
		return  # Während Drag keine Klicks
	set_active_slot(slot_index)
	slot_clicked.emit(slot_index)

# Icon für einen Slot setzen
func set_slot_icon(slot_index: int, icon_path: String):
	if slot_index >= 0 and slot_index < 9:
		var texture = load(icon_path)
		if texture:
			slot_icons[slot_index].texture = texture
		else:
			print("Icon nicht gefunden: ", icon_path)

# Cooldown für einen Slot anzeigen (remaining_time in Sekunden)
func set_slot_cooldown(slot_index: int, remaining_time: float):
	if slot_index < 0 or slot_index >= 9:
		return

	if remaining_time > 0:
		slot_cooldown_overlays[slot_index].visible = true
		slot_cooldown_labels[slot_index].visible = true
		slot_cooldown_labels[slot_index].text = "%.1f" % remaining_time
	else:
		slot_cooldown_overlays[slot_index].visible = false
		slot_cooldown_labels[slot_index].visible = false

# Level/XP UI erstellen
func _create_level_ui():
	var control = $Control

	# Ressourcen-Bar (Mana/Energie/Wut) - unter HP-Bar, oben links
	resource_bar = ProgressBar.new()
	resource_bar.name = "ResourceBar"
	resource_bar.position = Vector2(20, 50)
	resource_bar.size = Vector2(200, 18)
	resource_bar.show_percentage = false
	resource_bar.value = 0
	resource_bar.visible = false

	var resource_style = StyleBoxFlat.new()
	resource_style.bg_color = Color(0.2, 0.3, 0.9, 1.0)
	resource_bar.add_theme_stylebox_override("fill", resource_style)

	resource_label = Label.new()
	resource_label.name = "ResourceLabel"
	resource_label.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
	resource_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
	resource_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
	resource_bar.add_child(resource_label)
	control.add_child(resource_bar)

	# Level Label — wird in update_level() über XPLabel gesetzt, kein eigenes Node nötig
	level_label = Label.new()  # Dummy damit update_level() nicht crasht
	level_label.name = "LevelLabel"
	level_label.visible = false
	control.add_child(level_label)

	# Gold Label oben links
	gold_label = Label.new()
	gold_label.name = "GoldLabel"
	gold_label.position = Vector2(20, 94)
	gold_label.add_theme_font_size_override("font_size", 14)
	gold_label.add_theme_color_override("font_color", Color(1, 0.85, 0, 1))
	gold_label.text = "0 Gold"
	control.add_child(gold_label)

	# XP Bar — gleiche Breite wie Actionbar (468px), unten mittig, unter der Actionbar
	xp_bar = ProgressBar.new()
	xp_bar.name = "XPBar"
	xp_bar.anchor_left   = 0.5
	xp_bar.anchor_top    = 1.0
	xp_bar.anchor_right  = 0.5
	xp_bar.anchor_bottom = 1.0
	xp_bar.offset_left   = -234.0
	xp_bar.offset_right  = 234.0
	xp_bar.offset_top    = -18.0
	xp_bar.offset_bottom = -6.0
	xp_bar.show_percentage = false
	xp_bar.value = 0
	xp_bar.mouse_filter = Control.MOUSE_FILTER_IGNORE

	var xp_style = StyleBoxFlat.new()
	xp_style.bg_color = Color(0.15, 0.5, 0.9, 1.0)
	xp_bar.add_theme_stylebox_override("fill", xp_style)

	var xp_bg = StyleBoxFlat.new()
	xp_bg.bg_color = Color(0.1, 0.1, 0.15, 0.85)
	xp_bar.add_theme_stylebox_override("background", xp_bg)

	# XP Label zentriert in der Bar
	var xp_label = Label.new()
	xp_label.name = "XPLabel"
	xp_label.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
	xp_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
	xp_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
	xp_label.add_theme_font_size_override("font_size", 10)
	xp_label.add_theme_color_override("font_color", Color(1, 1, 1, 0.9))
	xp_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
	xp_bar.add_child(xp_label)
	control.add_child(xp_bar)

	# Castbar — direkt über der Aktionsleiste positioniert
	_create_castbar()

# Gold aktualisieren
func update_gold(amount: int):
	if gold_label:
		gold_label.text = str(amount) + " Gold"

# Ressourcen-Leiste aktualisieren (Mana/Energie/Wut)
func update_resource(current: int, maximum: int, resource_name: String):
	if resource_bar == null:
		return
	if maximum <= 0:
		resource_bar.visible = false
		return
	resource_bar.visible = true
	resource_bar.max_value = maximum
	resource_bar.value = current
	resource_label.text = str(current) + " / " + str(maximum)

	# Farbe je nach Ressourcen-Typ
	var style = resource_bar.get_theme_stylebox("fill") as StyleBoxFlat
	if style:
		match resource_name:
			"Mana":
				style.bg_color = Color(0.2, 0.3, 0.9, 1.0)  # Blau
			"Energie":
				style.bg_color = Color(0.9, 0.8, 0.1, 1.0)  # Gelb
			"Wut":
				style.bg_color = Color(0.8, 0.15, 0.1, 1.0)  # Rot

# Icon-Textur direkt setzen (für Consumables)
func set_slot_icon_texture(slot_index: int, texture: Texture2D):
	if slot_index >= 0 and slot_index < 9:
		slot_icons[slot_index].texture = texture

# Slot-Icon entfernen
func clear_slot_icon(slot_index: int):
	if slot_index >= 0 and slot_index < 9:
		slot_icons[slot_index].texture = null

# Stack-Anzahl auf Slot anzeigen
func set_slot_stack_count(slot_index: int, count: int):
	if slot_index < 0 or slot_index >= 9:
		return
	if count > 1:
		slot_stack_labels[slot_index].text = str(count)
		slot_stack_labels[slot_index].visible = true
	else:
		slot_stack_labels[slot_index].visible = false

# HP-Leiste und Text aktualisieren
func update_health(current_hp, max_hp):
	health_bar.max_value = max_hp
	health_bar.value = current_hp
	health_label.text = str(current_hp) + " / " + str(max_hp)

# Level und XP aktualisieren
func update_level(level: int, current_xp: int, xp_to_next: int):
	if level_label:
		level_label.text = "Lv " + str(level)
	if xp_bar:
		xp_bar.max_value = xp_to_next
		xp_bar.value = current_xp
		var xp_label = xp_bar.get_node_or_null("XPLabel")
		if xp_label:
			xp_label.text = "Lv %d   %d / %d XP" % [level, current_xp, xp_to_next]

# Aktions-Slot kurz golden hervorheben (0.1s)
func set_active_slot(index):
	action_slots[active_slot].self_modulate = Color(1, 1, 1)
	active_slot = index
	action_slots[active_slot].self_modulate = Color(1, 0.8, 0)
	await get_tree().create_timer(0.1).timeout
	action_slots[active_slot].self_modulate = Color(1, 1, 1)

# Drag & Drop: Highlight aktivieren/deaktivieren
func set_drag_active(active: bool):
	drag_active = active
	if not active:
		# Alle Highlights entfernen
		_clear_drag_highlight()

# Drag & Drop: Hover über Slots prüfen und gelben Rand setzen
func update_drag_hover(mouse_pos: Vector2):
	if not drag_active:
		return
	var hovered = get_slot_at_position(mouse_pos)
	if hovered == drag_highlight_slot:
		return  # Keine Änderung
	# Alten Highlight entfernen
	_clear_drag_highlight()
	# Neuen Highlight setzen (nur Slots 2-8)
	if hovered >= 0 and hovered <= 8:
		drag_highlight_slot = hovered
		var style = StyleBoxFlat.new()
		style.bg_color = Color(0.15, 0.15, 0.15)
		style.border_color = Color(1, 0.9, 0, 1)  # Gelber Rand
		style.set_border_width_all(3)
		action_slots[hovered].add_theme_stylebox_override("panel", style)

func _clear_drag_highlight():
	if drag_highlight_slot >= 0 and drag_highlight_slot < 9:
		action_slots[drag_highlight_slot].remove_theme_stylebox_override("panel")
	drag_highlight_slot = -1

# Gibt den Slot-Index zurück wenn mouse_pos über einem Action-Slot liegt, sonst -1
func get_slot_at_position(mouse_pos: Vector2) -> int:
	for i in range(9):
		var slot = action_slots[i]
		var rect = slot.get_global_rect()
		if rect.has_point(mouse_pos):
			return i
	return -1

func _create_castbar():
	# Eigene CanvasLayer für die Castbar
	var castbar_layer = CanvasLayer.new()
	castbar_layer.name = "CastbarLayer"
	castbar_layer.layer = 10
	add_child(castbar_layer)

	castbar_container = PanelContainer.new()
	castbar_container.name = "CastbarContainer"
	castbar_container.visible = false
	castbar_container.mouse_filter = Control.MOUSE_FILTER_IGNORE

	var style = StyleBoxFlat.new()
	style.bg_color = Color(0.1, 0.1, 0.1, 0.85)
	style.set_border_width_all(2)
	style.border_color = Color(0.6, 0.6, 0.6)
	style.set_corner_radius_all(4)
	castbar_container.add_theme_stylebox_override("panel", style)

	var vbox = VBoxContainer.new()
	vbox.mouse_filter = Control.MOUSE_FILTER_IGNORE
	castbar_container.add_child(vbox)

	castbar_label = Label.new()
	castbar_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
	castbar_label.add_theme_font_size_override("font_size", 13)
	castbar_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
	vbox.add_child(castbar_label)

	castbar = ProgressBar.new()
	castbar.custom_minimum_size = Vector2(300, 16)
	castbar.show_percentage = false
	castbar.mouse_filter = Control.MOUSE_FILTER_IGNORE

	var fill = StyleBoxFlat.new()
	fill.bg_color = Color(1.0, 0.7, 0.0, 1.0)
	fill.set_corner_radius_all(2)
	castbar.add_theme_stylebox_override("fill", fill)

	var bg = StyleBoxFlat.new()
	bg.bg_color = Color(0.2, 0.2, 0.2, 1.0)
	bg.set_corner_radius_all(2)
	castbar.add_theme_stylebox_override("background", bg)

	vbox.add_child(castbar)
	castbar_layer.add_child(castbar_container)

# Castbar anzeigen
func show_castbar(spell_name: String, cast_time: float):
	if castbar_container == null:
		return
	# Spell-Name übersetzen
	var display_name = spell_name
	match spell_name:
		"frostbolt": display_name = "Frostblitz"
	castbar_label.text = display_name + " (" + "%.1f" % cast_time + "s)"
	castbar.max_value = cast_time
	castbar.value = 0
	# Mittig über der Aktionsleiste positionieren
	var viewport_size = get_viewport().get_visible_rect().size
	castbar_container.position = Vector2(viewport_size.x / 2 - 160, viewport_size.y - 120)
	castbar_container.visible = true

# Castbar Fortschritt aktualisieren
func update_castbar(elapsed: float, total: float):
	if castbar == null:
		return
	castbar.value = elapsed
	var remaining = total - elapsed
	if remaining < 0:
		remaining = 0
	castbar_label.text = castbar_label.text.split("(")[0].strip_edges() + " (%.1f" % remaining + "s)"

# Castbar verstecken
func hide_castbar():
	if castbar_container:
		castbar_container.visible = false
