class_name UpgradeTreeNode
extends Control

signal node_selected(id: String)
signal node_hovered(id: String)
signal node_unhovered(id: String)

var node_id := ""
var definition: Dictionary = {}
var state := "locked"
var icon: Texture2D

func setup(id: String, data: Dictionary, current_state: String) -> void:
	node_id = id
	definition = data
	state = current_state
	custom_minimum_size = Vector2(118, 92)
	size = custom_minimum_size
	mouse_filter = Control.MOUSE_FILTER_STOP
	focus_mode = Control.FOCUS_ALL
	tooltip_text = str(data.get("detailed_text", "")) if state != "mystery" else "Unknown upgrade"
	var image_path := str(data.get("image_path", ""))
	if not image_path.is_empty() and ResourceLoader.exists(image_path):
		icon = load(image_path) as Texture2D
	mouse_entered.connect(_on_hovered)
	mouse_exited.connect(_on_unhovered)
	queue_redraw()

func _gui_input(event: InputEvent) -> void:
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
		grab_focus()
		node_selected.emit(node_id)
		accept_event()
	elif event.is_action_pressed("ui_accept") or event.is_action_pressed("action"):
		node_selected.emit(node_id)
		accept_event()

func _on_hovered() -> void:
	node_hovered.emit(node_id)
	queue_redraw()

func _on_unhovered() -> void:
	node_unhovered.emit(node_id)

func _draw() -> void:
	var theme_definition := _theme_definition()
	var states: Dictionary = theme_definition.get("states", {})
	var style: Dictionary = states.get(state, states.get("available", {}))
	var background := _as_color(style.get("background_color", Color("334155")))
	var border := _as_color(style.get("border_color", Color("94a3b8")))
	var text_color := _as_color(style.get("text_color", Color.WHITE))
	var border_width := float(style.get("border_width", 4.0))
	var center := size * 0.5
	var shape := str(theme_definition.get("shape", "square"))
	var points := _shape_points(shape, center, Vector2(54, 42))
	draw_colored_polygon(points, background)
	draw_polyline(PackedVector2Array(Array(points) + [points[0]]), border, border_width, true)
	if has_focus():
		var focus_points := _shape_points(shape, center, Vector2(57, 45))
		draw_polyline(PackedVector2Array(Array(focus_points) + [focus_points[0]]), Color("fde047"), 2.0, true)
	if icon != null and state != "mystery":
		draw_texture_rect(icon, Rect2(center.x - 13, 8, 26, 26), false)
	var text := "?" if state == "mystery" else str(definition.get("node_text", node_id))
	if state == "purchased":
		text = "[OK] " + text
	var baseline := center.y - 3.0 if icon == null else center.y + 9.0
	draw_string(ThemeDB.fallback_font, Vector2(8, baseline), text, HORIZONTAL_ALIGNMENT_CENTER, size.x - 16, 13, text_color)
	var displayed_cost := get_cost_text()
	if not displayed_cost.is_empty():
		draw_string(ThemeDB.fallback_font, Vector2(8, center.y + 25.0), displayed_cost, HORIZONTAL_ALIGNMENT_CENTER, size.x - 16, 11, text_color)

func get_cost_text() -> String:
	if state == "mystery":
		return ""
	if state == "purchased":
		return "OWNED"
	var cost := int(definition.get("cost", 0))
	return "FREE" if cost <= 0 else "%d COINS" % cost

func _theme_definition() -> Dictionary:
	var theme_id := str(definition.get("theme", ""))
	if DataCatalog.UPGRADE_THEMES.has(theme_id):
		return DataCatalog.UPGRADE_THEMES[theme_id]
	return DataCatalog.DEFAULT_UPGRADE_THEMES.values()[0]

func _as_color(value: Variant) -> Color:
	return value if value is Color else Color.from_string(str(value), Color.WHITE)

func _shape_points(shape: String, center: Vector2, half: Vector2) -> PackedVector2Array:
	match shape:
		"circle":
			var circle := PackedVector2Array()
			for index: int in range(32):
				var angle := TAU * float(index) / 32.0
				circle.append(center + Vector2(cos(angle) * half.x, sin(angle) * half.y))
			return circle
		"diamond":
			return PackedVector2Array([center + Vector2(0, -half.y), center + Vector2(half.x, 0), center + Vector2(0, half.y), center + Vector2(-half.x, 0)])
		"hexagon":
			return PackedVector2Array([center + Vector2(-half.x * 0.55, -half.y), center + Vector2(half.x * 0.55, -half.y), center + Vector2(half.x, 0), center + Vector2(half.x * 0.55, half.y), center + Vector2(-half.x * 0.55, half.y), center + Vector2(-half.x, 0)])
		_:
			return PackedVector2Array([center - half, center + Vector2(half.x, -half.y), center + half, center + Vector2(-half.x, half.y)])
