class_name RepairMinigame
extends CanvasLayer

signal repair_complete

const PUZZLES := {
	"vrac7": {
		"title": "RECONNECTION — MOTOR SYSTEM",
		"connections": [[0, 0], [1, 2], [3, 3]]
	},
	"iris3": {
		"title": "RECALIBRATION — OPTICAL SENSOR",
		"connections": [[0, 1], [2, 3]]
	},
	"scrap09": { 
		"title": "SELF-REPAIR — SCRAP-09",
		"connections": [[0, 0], [1, 2], [2, 3]]
	},
}

const GRID_SIZE := 4

var current_puzzle: Dictionary
var paths: Array = []
var active_path: int = -1
var solved_paths: Array = []

@onready var grid      := $Background/Panel/VBoxContainer/Grid
@onready var title_lbl := $Background/Panel/VBoxContainer/Title
@onready var status    := $Background/Panel/VBoxContainer/StatusLabel

# ── Lifecycle ─────────────────────────────────────────────────────────────────

func _ready() -> void:
	layer = 1000

	var panel := $Background/Panel
	panel.set_anchors_preset(Control.PRESET_CENTER)

	var vbox := $Background/Panel/VBoxContainer
	vbox.alignment = BoxContainer.ALIGNMENT_CENTER
	vbox.add_theme_constant_override("separation", 12)

	# Centre la grid horizontalement dans le VBox
	grid.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
	grid.size_flags_vertical   = Control.SIZE_SHRINK_CENTER

func _unhandled_input(event: InputEvent) -> void:
	if event.is_action_pressed("ui_cancel"):
		_cancel()

# ── API publique ──────────────────────────────────────────────────────────────

func open(robot_id: String) -> void:
	current_puzzle = PUZZLES[robot_id]
	title_lbl.text = current_puzzle["title"]
	paths.clear()
	solved_paths.clear()
	for _c in current_puzzle["connections"]:
		paths.append([])
		solved_paths.append(false)
	_set_hud_visible(false)
	_set_player_enabled(false)
	_build_grid()
	_update_status()
	show()

# ── Grille ────────────────────────────────────────────────────────────────────

func _build_grid() -> void:
	for child in grid.get_children():
		child.queue_free()

	# Taille fixe de la grille : GRID_SIZE * taille bouton + séparation
	var cell_size := 25
	var separation := 4
	var grid_px := GRID_SIZE * cell_size + (GRID_SIZE - 1) * separation
	grid.custom_minimum_size = Vector2(grid_px, grid_px)
	grid.columns = GRID_SIZE

	for row in GRID_SIZE:
		for col in GRID_SIZE:
			var btn := Button.new()
			btn.custom_minimum_size = Vector2(cell_size, cell_size)
			btn.name = "Cell_%d_%d" % [row, col]
			btn.add_theme_stylebox_override("normal", _make_stylebox(Color(0.15, 0.15, 0.15), 1.0))
			btn.add_theme_stylebox_override("hover",  _make_stylebox(Color(0.25, 0.25, 0.25), 1.0))

			if col == 0:
				var path_idx = _entry_for_row(row)
				if path_idx >= 0:
					btn.text = "0"
					btn.modulate = _color_for_path(path_idx)
			elif col == 3:
				var path_idx = _exit_for_row(row)
				if path_idx >= 0:
					btn.text = "X"
					btn.modulate = _color_for_path(path_idx)

			btn.pressed.connect(_on_cell_pressed.bind(row, col))
			grid.add_child(btn)

func _on_cell_pressed(row: int, col: int) -> void:
	var entry_idx = _entry_for_row(row)
	if col == 0 and entry_idx >= 0:
		active_path = entry_idx
		paths[active_path] = [Vector2i(row, col)]
		_refresh_grid()
		return

	if active_path < 0:
		return

	var last: Vector2i = paths[active_path].back() if paths[active_path].size() > 0 else Vector2i(-1, -1)
	var cell := Vector2i(row, col)

	if not _is_adjacent(last, cell):
		return

	for i in paths.size():
		if i == active_path:
			continue
		if cell in paths[i]:
			return

	paths[active_path].append(cell)

	var exit_row = current_puzzle["connections"][active_path][1]
	if col == 3 and row == exit_row:
		solved_paths[active_path] = true
		active_path = -1
		_refresh_grid()
		_update_status()
		_check_win()
		return

	_refresh_grid()
	_update_status()

# ── Victoire / Annulation ─────────────────────────────────────────────────────

func _check_win() -> void:
	if solved_paths.all(func(s): return s == true):
		await get_tree().create_timer(0.6).timeout
		repair_complete.emit()
		_close()

func _cancel() -> void:
	active_path = -1
	_close()

func _close() -> void:
	_set_hud_visible(true)
	_set_player_enabled(true)
	hide()

# ── Affichage ─────────────────────────────────────────────────────────────────

func _refresh_grid() -> void:
	for row in GRID_SIZE:
		for col in GRID_SIZE:
			var btn: Button = grid.get_node_or_null("Cell_%d_%d" % [row, col])
			if btn == null:
				continue
			var cell := Vector2i(row, col)
			var found := false

			for i in paths.size():
				if cell in paths[i]:
					var c := _color_for_path(i)
					var is_endpoint := (col == 0 or col == 3)
					btn.text = "●" if is_endpoint else "■"
					btn.modulate = Color.WHITE
					btn.add_theme_stylebox_override("normal", _make_stylebox(c, 0.5))
					btn.add_theme_color_override("font_color", c)
					found = true
					break

			if not found:
				btn.modulate = Color.WHITE
				btn.text = ""
				btn.add_theme_stylebox_override("normal", _make_stylebox(Color(0.15, 0.15, 0.15), 1.0))
				btn.remove_theme_color_override("font_color")
				var ei = _entry_for_row(row)
				var xi = _exit_for_row(row)
				if col == 0 and ei >= 0:
					btn.text = "●"
					btn.add_theme_color_override("font_color", _color_for_path(ei))
				elif col == 3 and xi >= 0:
					btn.text = "●"
					btn.add_theme_color_override("font_color", _color_for_path(xi))

func _update_status() -> void:
	var count := solved_paths.count(true)
	var total := solved_paths.size()
	if count == total:
		status.text = "REPAIR COMPLETE"
		status.add_theme_color_override("font_color", Color("#6daa45"))
	else:
		status.text = "%d / %d connections established" % [count, total]
		status.remove_theme_color_override("font_color")

# ── Helpers ───────────────────────────────────────────────────────────────────

func _set_hud_visible(visible: bool) -> void:
	var hud = get_tree().get_first_node_in_group("hud")
	if hud:
		hud.visible = visible

func _make_stylebox(color: Color, alpha: float) -> StyleBoxFlat:
	var sb := StyleBoxFlat.new()
	sb.bg_color = Color(color.r, color.g, color.b, alpha)
	sb.corner_radius_top_left    = 4
	sb.corner_radius_top_right   = 4
	sb.corner_radius_bottom_left = 4
	sb.corner_radius_bottom_right = 4
	return sb

func _entry_for_row(row: int) -> int:
	for i in current_puzzle["connections"].size():
		if current_puzzle["connections"][i][0] == row:
			return i
	return -1

func _exit_for_row(row: int) -> int:
	for i in current_puzzle["connections"].size():
		if current_puzzle["connections"][i][1] == row:
			return i
	return -1

func _is_adjacent(a: Vector2i, b: Vector2i) -> bool:
	return abs(a.x - b.x) + abs(a.y - b.y) == 1

func _color_for_path(idx: int) -> Color:
	var colors := [Color("#f4c430"), Color("#5bc8f5"), Color("#f47c3c")]
	return colors[idx % colors.size()]

func _set_player_enabled(enabled: bool) -> void:
	var player = get_tree().get_first_node_in_group("player")
	print("_set_player_enabled: ", enabled, " | player trouvé: ", player)
	if player:
		player.set_process(enabled)
		player.set_physics_process(enabled)
		player.set_process_unhandled_input(enabled)
		player.is_locked = false
		if not enabled and player is CharacterBody2D:
			player.velocity = Vector2.ZERO
