extends UIPage

# UI Node References
@onready var list_container = $BG/Option/Info
@onready var previous_button = $BG/Title/previous/Button
@onready var next_button = $BG/Title/next/Button
@onready var title_label = $BG/Title/Title

# Configuration
var items_per_page: int = 7 # 每页显示的选项数量

# Data Storage
var gameplay_list_nodes: Array[VBoxContainer] = [] # 存储 List_1, List_2 等节点
var option_nodes_per_list: Array = [] # 存储每个 List 对应的 option_X 按钮数组
var all_enabled_gameplays: Array = [] # 存储筛选后的玩法数据 { "name": String, "data": Dictionary }

# State
var total_pages: int = 0
var current_page_index: int = 0
var selected_gameplay_key: String = "" # 当前逻辑上选中的项的 Key (用于确认)
var currently_selected_button: Button = null # 当前高亮/聚焦的按钮节点引用
var initial_key_to_highlight: String = "" # 弹窗打开时需要高亮的 Key (由父节点设置)

func _ready():
	super._ready() # 调用父类的 _ready() (如果 UIPage 中有 _ready() 逻辑)
	# 1. 获取 List 节点 (与原版一致)
	for i in range(1, 4): # 检查 List_1, List_2, List_3
		var list_node = list_container.get_node_or_null("List_" + str(i))
		if list_node:
			gameplay_list_nodes.append(list_node)
		else:
			break

	if gameplay_list_nodes.is_empty():
		printerr("错误：在 gameplay.tscn 中未找到 List 节点！无法显示选项。")
		set_process(false)
		return

	# 2. 获取每个 List 内的 Option 节点 (与原版一致)
	for list_node in gameplay_list_nodes:
		var current_list_options: Array = []
		for i in range(1, items_per_page + 1):
			var option_node = list_node.get_node_or_null("option_" + str(i))
			if option_node and option_node is Button:
				current_list_options.append(option_node)
			else:
				push_warning("警告：在 %s 中未能找到 option_%d 按钮" % [list_node.name, i])
		option_nodes_per_list.append(current_list_options)

	# 3. 连接按钮信号 (与原版一致)
	if previous_button:
		if not previous_button.pressed.is_connected(_on_previous_pressed):
			previous_button.pressed.connect(_on_previous_pressed)
	else: printerr("错误：在 gameplay.tscn 中未找到 Previous 按钮")

	if next_button:
		if not next_button.pressed.is_connected(_on_next_pressed):
			next_button.pressed.connect(_on_next_pressed)
	else: printerr("错误：在 gameplay.tscn 中未找到 Next 按钮")

	# 4. 连接 visibility_changed 信号 (与原版一致)
	if not is_connected("visibility_changed", _on_visibility_changed):
		visibility_changed.connect(_on_visibility_changed)

	# 5. 移除 _ready 中的初始数据加载和显示更新
	#    这些逻辑现在完全由 _on_visibility_changed -> reset_display 处理

# --- Visibility Change Handler ---
func _on_visibility_changed():
	if is_visible_in_tree():
		print("Gameplay: 弹窗变为可见，调用 reset_display()")
		reset_display() # 当变为可见时调用 reset
	# else: # 可选：隐藏时的清理逻辑
	#	 print("Gameplay: 弹窗变为隐藏。")

# --- 新增：用于父节点设置初始选中项 ---
func set_initial_selection(key: String):
	"""
	由父节点 (task_development) 在显示此弹窗前调用，
	传递当前在 task_info 中选中的玩法 Key。
	"""
	initial_key_to_highlight = key
	print("Gameplay: 父节点设置初始高亮 Key 为: '%s'" % initial_key_to_highlight)


# --- Data Processing and Display Logic ---

func _process_gameplay_data(all_gameplays_data: Dictionary):
	"""【修改】根据从 GameState 获取的玩法数据，筛选出启用的玩法，并计算总页数。"""
	all_enabled_gameplays.clear()
	if all_gameplays_data.is_empty():
		push_warning("警告：接收到的玩法数据为空。")
		total_pages = 0
		return

	# 遍历从 GameState 获取的玩法字典
	for gameplay_name in all_gameplays_data:
		var gameplay_info = all_gameplays_data[gameplay_name]
		# 检查是否为字典且 "enabled" 字段为 true
		if typeof(gameplay_info) == TYPE_DICTIONARY and gameplay_info.get("enabled", false) == true:
			all_enabled_gameplays.append({"name": gameplay_name, "data": gameplay_info})
		# else: # Debugging: 可以取消注释来看哪些被过滤了
		#	 print("Gameplay: 过滤掉未启用或格式错误的玩法: ", gameplay_name)

	# 根据筛选结果计算总页数
	if items_per_page > 0:
		total_pages = ceil(float(all_enabled_gameplays.size()) / items_per_page)
	else:
		total_pages = 0
		printerr("错误：items_per_page 为零，无法计算页数。")

	print("Gameplay: 处理完成，找到 %d 个启用的玩法，共 %d 页。" % [all_enabled_gameplays.size(), total_pages])

func reset_display():
	# 1. 重置本地状态变量
	currently_selected_button = null
	selected_gameplay_key = ""

	# 1b. 【修改】从 MainController 的共享数据中获取初始应选中的玩法 Key
	#     这个值将覆盖之前可能通过 set_initial_selection 设置的值（如果该方法在 reset_display 前被调用）。
	#     请确保 "initial_selected_gameplay" 是您在 shared_workflow_data 中用于此目的的正确键名。
	initial_key_to_highlight = get_main_data("玩法", "")
	if not initial_key_to_highlight.is_empty():
		print("Gameplay (reset_display): 从 get_main_data 获取到初始高亮 Key: '%s'" % initial_key_to_highlight)
	else:
		# 如果 get_main_data 没有提供有效的 Key (返回空字符串或默认值),
		# initial_key_to_highlight 将是空字符串。
		# 如果之前 set_initial_selection 被调用并设置了一个非空值，该值已被这里的空字符串覆盖。
		# 如果希望保留 set_initial_selection 的值作为后备，逻辑需要调整，
		# 但根据“来自get_main_data”的表述，这里直接取用 get_main_data 的结果。
		print("Gameplay (reset_display): 未从 get_main_data 获取到初始高亮 Key，或 Key 为空。")


	# 2. 【保持不变】从 GameState 加载并处理所有可显示的玩法数据
	if not GameState:
		printerr("错误：GameState 在 reset_display 期间不可用。")
		total_pages = 0
		all_enabled_gameplays.clear()
		_update_display() # 即使没有数据也要更新显示（显示空状态）
		return

	var task_dev_data = GameState.get_value("task_development", {})
	if task_dev_data.is_empty():
		printerr("错误：从 GameState 获取 'task_development' 数据失败。")
		total_pages = 0
		all_enabled_gameplays.clear()
	else:
		var all_gameplays_data = task_dev_data.get("gameplays", {})
		_process_gameplay_data(all_gameplays_data) # 重新处理数据，计算 total_pages

	# 3. 【逻辑不变，但使用来自 get_main_data 的 initial_key_to_highlight】
	#    根据 initial_key_to_highlight 确定初始页面
	current_page_index = 0 # 默认为第一页
	var found_initial_key = false
	if total_pages > 0 and not initial_key_to_highlight.is_empty():
		# 查找 initial_key_to_highlight 所在的索引和页面
		for i in range(all_enabled_gameplays.size()):
			if all_enabled_gameplays[i].name == initial_key_to_highlight:
				current_page_index = int(floor(float(i) / items_per_page))
				found_initial_key = true
				print("Gameplay: 找到需要初始高亮的 Key '%s' (来自 get_main_data 或后续处理) 在索引 %d, 目标页面 %d" % [initial_key_to_highlight, i, current_page_index])
				break # 找到了，停止循环
		if not found_initial_key:
			print("Gameplay: 需要初始高亮的 Key '%s' (来自 get_main_data) 未在启用的玩法中找到，将显示第一页。" % initial_key_to_highlight)
			# 保持 current_page_index 为 0
			initial_key_to_highlight = "" # 清空，避免后续 _update_display 尝试高亮不存在的项

	# 确保页面索引有效
	if total_pages == 0:
		current_page_index = 0
	elif current_page_index >= total_pages:
		current_page_index = total_pages - 1
	elif current_page_index < 0:
		current_page_index = 0

	# 4. 触发显示更新
	_update_display()

func _update_display():
	"""【更新版】更新列表的可见性并填充当前页面的内容。
	   现在将“经验”和“成本”显示为整数。
	"""
	# --- 处理无数据情况 ---
	if gameplay_list_nodes.is_empty():
		print("Gameplay: 无可用的 List 节点。")
		if title_label: title_label.text = "玩法选择"
		return

	if total_pages == 0:
		for list_node in gameplay_list_nodes: list_node.visible = false
		print("Gameplay: 没有启用的玩法选项可供显示。")
		if title_label: title_label.text = "玩法选择 (无可用)"
		# 确保按钮也禁用或隐藏
		if previous_button: previous_button.disabled = true
		if next_button: next_button.disabled = true
		return
	else:
		# 确保按钮状态正确 (启用/禁用基于页数)
		if previous_button: previous_button.disabled = (total_pages <= 1)
		if next_button: next_button.disabled = (total_pages <= 1)


	# --- 更新页面索引 (循环) ---
	# 注意: reset_display 设置了初始页, 取模主要用于翻页
	if total_pages > 0 : # 避免除以零
		current_page_index = current_page_index % total_pages
		if current_page_index < 0:
			current_page_index += total_pages
	else:
		current_page_index = 0


	# --- 更新标题 ---
	if title_label:
		var display_page_number = current_page_index + 1 # 显示给用户的页码从1开始
		title_label.text = "玩法选择 %d/%d" % [display_page_number, total_pages]

	# --- 更新 List 可见性 ---
	# 确保只有一个 List 节点是可见的，即当前页对应的 List
	for i in range(gameplay_list_nodes.size()):
		gameplay_list_nodes[i].visible = (i == current_page_index)

	# --- 填充可见列表并查找要高亮的按钮 ---
	var button_to_highlight: Button = null
	var first_enabled_button_on_page: Button = null # 如果 initial_key 不在本页，则使用此按钮

	# 检查当前页索引是否在有效范围内
	if current_page_index < option_nodes_per_list.size():
		var current_options = option_nodes_per_list[current_page_index] # 获取当前页的所有按钮节点
		var start_index = current_page_index * items_per_page # 计算当前页数据在 all_enabled_gameplays 中的起始索引

		# 遍历当前页的按钮槽位
		for i in range(current_options.size()):
			var option_button = current_options[i] # 获取具体的按钮节点
			var item_index = start_index + i # 计算此按钮对应的数据索引

			# --- 断开旧信号 ---
			# 确保在连接新信号前断开旧的，防止重复连接
			if option_button.pressed.is_connected(_on_option_selected):
				option_button.pressed.disconnect(_on_option_selected)

			# 检查数据索引是否在有效范围内
			if item_index < all_enabled_gameplays.size():
				# 获取对应的玩法数据
				var gameplay_entry = all_enabled_gameplays[item_index]
				var gameplay_name = gameplay_entry.name
				var gameplay_data = gameplay_entry.data # 这是包含 Cost, Experience, Popularity 等信息的字典

				# 获取按钮内部用于显示信息的 Row 节点
				var row = option_button.get_node_or_null("Row")
				if row:
					# 填充标签文本
					var title_label_in_row = row.get_node_or_null("Title")
					var exp_label = row.get_node_or_null("Experience")
					var pop_label = row.get_node_or_null("Popularity")
					# 查找成本标签，兼容 "Cost" 和 "cost" 两种可能的节点名
					var cost_label = row.get_node_or_null("Cost") if row.has_node("Cost") else row.get_node_or_null("cost")

					# 设置标题
					if title_label_in_row: title_label_in_row.text = gameplay_name

					# 【修改】设置经验值，显示为整数
					if exp_label:
						var experience_value = gameplay_data.get("Experience", 0.0) # 获取原始值
						exp_label.text = str(int(experience_value)) # 转为整数再转为字符串

					# 【保持】设置流行度，保持原始字符串显示
					if pop_label:
						var popularity_value = gameplay_data.get("Popularity", "未知") # 获取原始值
						pop_label.text = str(popularity_value) # 直接转为字符串

					# 【修改】设置成本，显示为整数
					if cost_label:
						var cost_value = gameplay_data.get("Cost", 0.0) # 获取原始值
						cost_label.text = str(int(cost_value)) # 转为整数再转为字符串

					# 设置按钮可见、可用，并存储玩法名称到元数据
					option_button.visible = true
					option_button.disabled = false
					option_button.set_meta("gameplay_name", gameplay_name)

					# --- 连接新信号 (使用 bind) ---
					# 传递玩法名称和按钮节点本身给处理函数
					option_button.pressed.connect(_on_option_selected.bind(gameplay_name, option_button))

					# 记录本页第一个可用的按钮，作为备选高亮目标
					if first_enabled_button_on_page == null:
						first_enabled_button_on_page = option_button

					# 检查此按钮是否是需要初始高亮的按钮
					if not initial_key_to_highlight.is_empty() and gameplay_name == initial_key_to_highlight:
						button_to_highlight = option_button
						# print("Gameplay: 找到需要初始高亮的按钮: ", button_to_highlight.name) # Debug

				else: # 未找到 Row 节点
					push_warning("警告：在按钮 %s 中未找到 Row 节点" % option_button.get_path())
					option_button.visible = false # 隐藏按钮以避免显示不完整
					option_button.disabled = true
			else: # 此槽位没有对应的启用玩法数据 (例如最后一页不满)
				option_button.visible = false # 隐藏按钮
				option_button.disabled = true
	else:
		# 这种情况理论上不应发生，除非页面计算或节点结构有问题
		printerr("错误：当前页面索引 %d 超出 option_nodes_per_list 的范围 (大小 %d)" % [current_page_index, option_nodes_per_list.size()])

	# --- 设置初始高亮和焦点 ---
	# 优先高亮 initial_key_to_highlight 对应的按钮
	if button_to_highlight:
		# print("Gameplay: 尝试高亮指定按钮: ", button_to_highlight.name) # Debug
		_set_initial_highlight(button_to_highlight)
	# 如果没有指定按钮或指定按钮不在当前页，则高亮当前页的第一个可用按钮
	elif first_enabled_button_on_page:
		print("Gameplay: 初始 Key '%s' 不在本页或为空。高亮本页第一个按钮: %s" % [initial_key_to_highlight, first_enabled_button_on_page.name])
		_set_initial_highlight(first_enabled_button_on_page)
	# 如果当前页没有任何可用按钮
	else:
		print("Gameplay: 本页没有可供高亮的按钮。")
		currently_selected_button = null # 确保没有按钮被标记为选中
		selected_gameplay_key = "" # 确保没有 Key 被标记为选中

# (Helper) 设置初始高亮和焦点 (与原版类似，增加日志)
func _set_initial_highlight(button_to_highlight: Button):
	if not is_instance_valid(button_to_highlight):
		printerr("错误：传递给 _set_initial_highlight 的按钮无效。")
		currently_selected_button = null
		selected_gameplay_key = ""
		return

	# print("Gameplay: 设置高亮按钮: ", button_to_highlight.name) # Debug
	currently_selected_button = button_to_highlight
	selected_gameplay_key = button_to_highlight.get_meta("gameplay_name", "") # 同时设置 Key
	# print("Gameplay: currently_selected_button 设置为: ", currently_selected_button.name) # Debug
	# print("Gameplay: selected_gameplay_key 设置为: '", selected_gameplay_key, "'") # Debug

	# 延迟调用 grab_focus 确保按钮已准备好接收焦点
	if currently_selected_button and currently_selected_button.is_inside_tree():
		# print("Gameplay: 尝试为按钮 call_deferred('grab_focus'): ", currently_selected_button.name) # Debug
		currently_selected_button.call_deferred("grab_focus")
	else:
		print("Gameplay: 按钮无效或不在场景树中，无法获取焦点。")


# --- Signal Handlers ---

func _on_previous_pressed():
	if total_pages > 1: # 仅当有多页时才翻页
		current_page_index -= 1
		# 循环由 _update_display 处理
		_update_display()

func _on_next_pressed():
	if total_pages > 1: # 仅当有多页时才翻页
		current_page_index += 1
		# 循环由 _update_display 处理
		_update_display()

# 【修改】处理选项按钮按下事件 (与原版类似，增加日志)
func _on_option_selected(gameplay_name: String, button_node: Button):
	"""当选项按钮被按下时调用。"""
	if not is_instance_valid(button_node):
		printerr("错误：在 _on_option_selected 中收到无效按钮节点，Key: " + gameplay_name)
		return

	if button_node == currently_selected_button:
		# --- 双击 (或点击已选中的按钮) ---
		print("Gameplay: 检测到双击或确认点击: ", gameplay_name)
		_confirm_and_close(gameplay_name) # 确认此选择
	else:
		# --- 首次点击或点击不同按钮 ---
		print("Gameplay: 选中 (高亮) 玩法: ", gameplay_name)
		currently_selected_button = button_node
		selected_gameplay_key = gameplay_name # 更新 Key，以便后续可能的确认

		# 更新视觉焦点
		button_node.grab_focus()

# 【修改】确认选择并关闭弹窗的逻辑
func _confirm_and_close(key_to_confirm: String):
	"""更新父节点并关闭此弹窗。"""
	if key_to_confirm.is_empty():
		printerr("错误：尝试确认一个空的玩法 Key。")
		return

	print("Gameplay: 确认选择: ", key_to_confirm)

	set_main_data("玩法", key_to_confirm)
	go_next()
