extends Node2D

# 1、准备六边形网格地图和玩家
@onready var tile_map_layer: TileMapLayer = $TileMapLayer
@onready var player: Node2D = $Player
@onready var marked_layer: TileMapLayer = $MarkedLayer

# 2、获取起点和步数限制
var init_position: Vector2i = Vector2i(0, 0)
var step_limit: int = 3


var path_info: Dictionary = {} # 记录路径信息
func _ready() -> void:
	# 将玩家起点位置
	player.global_position = tile_map_layer.map_to_local(init_position)
	search_and_show_path(init_position)

# 搜索并展示
func search_and_show_path(start_position: Vector2i):
	search_path(start_position)
	print("当前位置可以移动到的坐标: ", path_info)
	highlight_cells()

# 3、使用广度优先搜索探索
# 4、记录路径信息
func search_path(start_position: Vector2i) -> void:
	# 清空路径信息
	path_info = {}
	# 记录路径信息
	path_info[start_position] = {
		"front_point": null,
		"step": 0
	}
	# 记录已访问位置
	var visited: Dictionary = {}
	visited[start_position] = true

	# 记录待探索位置
	var queue: Array[Vector2i] = [start_position]
	while not queue.is_empty():
		var current_position: Vector2i = queue.pop_front()
		if path_info[current_position]["step"] >= step_limit:
			continue
		var surrounding_cells: Array[Vector2i] = tile_map_layer.get_surrounding_cells(current_position)
		for cell in surrounding_cells:
			# 如果cell没有tile_data，则跳过
			if tile_map_layer.get_cell_tile_data(cell) == null:
				continue
			# 如果cell已经访问过，则跳过
			if not visited.has(cell):
				visited[cell] = true
				# 记录待探索位置
				queue.append(cell)
				# 记录路径信息
				path_info[cell] = {
					"front_point": current_position,
					"step": path_info[current_position]["step"] + 1,
				}

var marked_cell_source_id = 0
var marked_cell_coord = Vector2i(20, 0)

# 5、高亮可以移动到的坐标
func highlight_cells():
	# 清空标记层
	marked_layer.clear()
	for cell_coord in path_info.keys():
		# 设置标记层
		marked_layer.set_cell(cell_coord, marked_cell_source_id, marked_cell_coord)

func _input(event: InputEvent) -> void:
	# 7、当玩家鼠标点击时获取坐标并处理
	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
		var mouse_pos = get_global_mouse_position()
		var map_coord = tile_map_layer.local_to_map(tile_map_layer.to_local(mouse_pos))
		print(map_coord)
		# 判断是否可以移动到对应位置
		if tile_map_layer.get_cell_tile_data(map_coord) != null and path_info.has(map_coord):
			# 8、反向获得路径
			var path: Array[Vector2i] = []
			var current: Vector2i = map_coord
			while path_info.has(current):
				# 将路径点添加到路径数组前方
				path.push_front(current)
				var front_point = path_info[current]["front_point"]
				if front_point == null:
					break
				current = front_point

			print("移动路径: ", path)
			# 移动玩家到目标位置
			await move_player_along_path(path)
			# 更新起点并重新搜索路径
			search_and_show_path(map_coord)

# 9、让玩家沿着路径移动
func move_player_along_path(path: Array[Vector2i]) -> void:
	if path.is_empty():
		return
	# 删除当前位置
	path.pop_front()
	# 更新玩家位置到目标点
	while not path.is_empty():
		var next_position: Vector2i = path.pop_front()
		var tween = get_tree().create_tween()
		tween.tween_property(player, "global_position", tile_map_layer.map_to_local(next_position), 1)
		await tween.finished
