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 # 每页显示的选项数量 (保持与原 theme.gd 一致)

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

# State
var total_pages: int = 0
var current_page_index: int = 0
var selected_theme_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 节点 (与原版 theme.gd 类似，但使用 gameplay.gd 的错误处理)
	for i in range(1, 7): # 假设最多有 List_6 (与原 theme.gd 匹配)
		var list_node = list_container.get_node_or_null("List_" + str(i))
		if list_node:
			theme_list_nodes.append(list_node)
		else:
			break # 假设 List 节点是连续的

	if theme_list_nodes.is_empty():
		printerr("错误：在 theme.tscn 中未找到 List 节点！无法显示选项。")
		set_process(false) # 禁用处理，因为没有UI元素
		return

	# 2. 获取每个 List 内的 Option 节点 (与原版 theme.gd 类似)
	for list_node in theme_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:
				# 使用 gameplay.gd 的警告格式
				push_warning("警告：在 %s 中未能找到 option_%d 按钮" % [list_node.name, i])
		option_nodes_per_list.append(current_list_options)

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

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

	# 4. 连接 visibility_changed 信号 (与 gameplay.gd 一致)
	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 (与 gameplay.gd 一致) ---
func _on_visibility_changed():
	if is_visible_in_tree():
		print("Theme: 弹窗变为可见，调用 reset_display()")
		reset_display() # 当变为可见时调用 reset
	# else: # 可选：隐藏时的清理逻辑
	#	 print("Theme: 弹窗变为隐藏。")

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


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

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

	# 遍历从 GameState 获取的题材字典
	for theme_name in all_themes_data:
		var theme_info = all_themes_data[theme_name]
		# 检查是否为字典且 "enabled" 字段为 true
		if typeof(theme_info) == TYPE_DICTIONARY and theme_info.get("enabled", false) == true:
			all_enabled_themes.append({"name": theme_name, "data": theme_info})
		# else: # Debugging
		#	 print("Theme: 过滤掉未启用或格式错误的题材: ", theme_name)

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

	print("Theme: 处理完成，找到 %d 个启用的题材，共 %d 页。" % [all_enabled_themes.size(), total_pages])


func reset_display():
	"""【修改】重置状态，从共享数据获取初始选中项，从 GameState 加载所有可选数据，并准备更新显示。"""
	print("Theme: 重置显示状态 (reset_display)。")
	# 1. 重置本地状态变量
	currently_selected_button = null
	selected_theme_key = "" # 当前逻辑上选中的项的 Key

	# 1b. 【修改】从 MainController 的共享数据中获取初始应选中的题材 Key
	#     使用键名 "题材"。如果未找到该键，默认为空字符串。
	initial_key_to_highlight = get_main_data("题材", "") # <--- 从共享数据获取初始高亮项
	
	if not initial_key_to_highlight.is_empty():
		print("Theme (reset_display): 从 get_main_data(\"题材\") 获取到初始高亮 Key: '%s'" % initial_key_to_highlight)
	else:
		# 如果 get_main_data 没有提供有效的 Key (例如 "题材" 键不存在或其值为空字符串),
		# initial_key_to_highlight 将是空字符串。
		print("Theme (reset_display): 未从 get_main_data(\"题材\") 获取到初始高亮 Key，或 Key 为空。将尝试高亮第一页的第一个项目。")

	# 2. 【保持不变】从 GameState 重新加载并处理所有可显示的题材数据
	if not GameState:
		printerr("错误：GameState 在 reset_display 期间不可用。")
		total_pages = 0
		all_enabled_themes.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_themes.clear()
	else:
		# --- 从 task_development 中获取 themes ---
		var all_themes_data = task_dev_data.get("themes", {})
		_process_theme_data(all_themes_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_themes.size()):
			if all_enabled_themes[i].name == initial_key_to_highlight:
				current_page_index = int(floor(float(i) / items_per_page)) # 设置目标页面
				found_initial_key = true
				print("Theme: 找到需要初始高亮的 Key '%s' (来自 get_main_data(\"题材\")) 在索引 %d, 目标页面 %d" % [initial_key_to_highlight, i, current_page_index])
				break # 找到了，停止循环
		if not found_initial_key:
			print("Theme: 需要初始高亮的 Key '%s' (来自 get_main_data(\"题材\")) 未在启用的题材中找到。将显示第一页，并尝试高亮该页的第一个项目。" % initial_key_to_highlight)
			# 保持 current_page_index 为 0
			initial_key_to_highlight = "" # 清空，因为未找到，避免后续 _update_display 尝试高亮不存在的项
	# else: initial_key_to_highlight 为空, current_page_index 保持为 0 (第一页)

	# 确保页面索引有效 (与 gameplay.gd 一致)
	if total_pages == 0:
		current_page_index = 0
	elif current_page_index >= total_pages: # 如果计算出的页面超出范围
		current_page_index = total_pages - 1 if total_pages > 0 else 0
	elif current_page_index < 0: # 理论上不应发生
		current_page_index = 0

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

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

	if total_pages == 0:
		for list_node in theme_list_nodes: list_node.visible = false
		print("Theme: 没有启用的题材选项可供显示。")
		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)

	# --- 更新页面索引 (循环) (与 gameplay.gd 一致) ---
	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

	# --- 更新标题 (与 gameplay.gd 一致) ---
	if title_label:
		var display_page_number = current_page_index + 1
		title_label.text = "题材选择 %d/%d" % [display_page_number, total_pages]

	# --- 更新 List 可见性 (与 gameplay.gd 一致) ---
	for i in range(theme_list_nodes.size()):
		theme_list_nodes[i].visible = (i == current_page_index)

	# --- 填充可见列表并查找要高亮的按钮 (与 gameplay.gd 类似) ---
	var button_to_highlight: Button = null
	var first_enabled_button_on_page: Button = null

	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

		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_themes.size():
				var theme_entry = all_enabled_themes[item_index]
				var theme_name = theme_entry.name
				var theme_data = theme_entry.data # 包含 Cost, Experience, Popularity 等

				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")
					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 = theme_name

					# 【修改】设置经验值，显示为整数
					if exp_label:
						var experience_value = theme_data.get("Experience", 0.0)
						exp_label.text = str(int(experience_value))

					# 【保持】设置流行度，保持原始字符串显示
					if pop_label:
						var popularity_value = theme_data.get("Popularity", "未知")
						pop_label.text = str(popularity_value)

					# 【修改】设置成本，显示为整数
					if cost_label:
						var cost_value = theme_data.get("Cost", 0.0)
						cost_label.text = str(int(cost_value))

					option_button.visible = true
					option_button.disabled = false
					option_button.set_meta("theme_name", theme_name) # 存储题材名称

					# --- 连接新信号 (使用 bind) ---
					option_button.pressed.connect(_on_option_selected.bind(theme_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 theme_name == initial_key_to_highlight:
						button_to_highlight = option_button
						# print("Theme: 找到需要初始高亮的按钮: ", 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()])

	# --- 设置初始高亮和焦点 (与 gameplay.gd 一致) ---
	if button_to_highlight:
		_set_initial_highlight(button_to_highlight)
	elif first_enabled_button_on_page:
		print("Theme: 初始 Key '%s' 不在本页或为空。高亮本页第一个按钮: %s" % [initial_key_to_highlight, first_enabled_button_on_page.name])
		_set_initial_highlight(first_enabled_button_on_page)
	else:
		print("Theme: 本页没有可供高亮的按钮。")
		currently_selected_button = null
		selected_theme_key = ""

# (Helper) 设置初始高亮和焦点 (与 gameplay.gd 一致)
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_theme_key = ""
		return

	# print("Theme: 设置高亮按钮: ", button_to_highlight.name) # Debug
	currently_selected_button = button_to_highlight
	# --- 修改元数据键名 ---
	selected_theme_key = button_to_highlight.get_meta("theme_name", "") # 同时设置 Key
	# print("Theme: currently_selected_button 设置为: ", currently_selected_button.name) # Debug
	# print("Theme: selected_theme_key 设置为: '", selected_theme_key, "'") # Debug

	if currently_selected_button and currently_selected_button.is_inside_tree():
		# print("Theme: 尝试为按钮 call_deferred('grab_focus'): ", currently_selected_button.name) # Debug
		currently_selected_button.call_deferred("grab_focus")
	else:
		print("Theme: 按钮无效或不在场景树中，无法获取焦点。")


# --- Signal Handlers ---

# (与 gameplay.gd 一致)
func _on_previous_pressed():
	if total_pages > 1:
		current_page_index -= 1
		_update_display()

# (与 gameplay.gd 一致)
func _on_next_pressed():
	if total_pages > 1:
		current_page_index += 1
		_update_display()

# 【修改】处理选项按钮按下事件 (与 gameplay.gd 一致)
func _on_option_selected(theme_name: String, button_node: Button):
	"""当选项按钮被按下时调用。"""
	if not is_instance_valid(button_node):
		# --- 修改错误信息中的 Key 类型 ---
		printerr("错误：在 _on_option_selected 中收到无效按钮节点，Key: " + theme_name)
		return

	if button_node == currently_selected_button:
		# --- 双击 (或点击已选中的按钮) ---
		print("Theme: 检测到双击或确认点击: ", theme_name)
		_confirm_and_close(theme_name) # 确认此选择
	else:
		# --- 首次点击或点击不同按钮 ---
		print("Theme: 选中 (高亮) 题材: ", theme_name)
		currently_selected_button = button_node
		selected_theme_key = theme_name # 更新 Key

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

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

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

	set_main_data("题材", key_to_confirm)
	go_next()
