# ui_base.gd
class_name UIPage
extends Control

# --- Signals ---
signal navigate_requested(target_page_node: Control)
signal workflow_end_requested(is_confirm_and_trigger_action: bool)

# --- Exported Variables for Inspector ---
## The page to navigate to when a "next" or "confirm" action is triggered.
@export var next_ui_node_path: NodePath
## The page to navigate to when a "back" or "cancel" action is triggered.
@export var back_ui_node_path: NodePath
## For sub-pages, this is their direct parent page (e.g., A is parent of A_1).
## Used if back_ui_node_path is not set for a sub-page, to return to its parent.
@export var parent_page_node_path: NodePath
## If true (default), this page will be hidden when go_next() is called and
## a next_ui_node_path is successfully navigated to.
## If false, this page will remain visible.
@export var hide_on_next: bool = true

# --- Internal Variables ---
var main_controller # Will hold reference to Main.gd

func _ready():
	# Attempt to find the Main controller. Assumes Main is the owner or a known path.
	if owner and owner.has_method("get_shared_data"): # Simple check if owner is Main
		main_controller = owner

# --- Godot Input Handling ---
func _input(event):
	# Only process input if the page is currently visible and the feature is enabled
	if not visible:
		return

	if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT and event.is_pressed():
		print("UIPage '", name, "' detected right-click. Attempting to go back.")
		go_back()
		get_viewport().set_input_as_handled() # Consume the event so other nodes don't process it

# --- Public Methods ---
func show_page():
	# 仅当页面之前是不可见状态时，才设置 visible = true。
	# 或者更简单地，总是设置 visible = true，因为重复设置 true 没有副作用。
	if not visible:
		visible = true

func hide_page():
	# Only call _on_page_deactivated if the page was previously visible.
	if visible:
		_on_page_deactivated() # Call the overridable method before hiding
		visible = false
	# else:
	#   print("UIPage " + name + " already hidden. Not re-deactivating.")

func _on_page_activated():
	# Base implementation can be empty or log
	print("UIPage activated: " + name)
	pass

func _on_page_deactivated():
	# Base implementation can be empty or log
	print("UIPage deactivated: " + name)
	pass

# --- Navigation Methods (to be called by buttons on this page) ---
func go_next():
	if not next_ui_node_path.is_empty():
		var target_node = get_node_or_null(next_ui_node_path)
		if target_node and target_node is Control: # Ensure target_node is a Control, ideally a UIPage
			emit_signal("navigate_requested", target_node)
		else:
			printerr("Next UI node not found or not a Control: ", next_ui_node_path, " from page ", name)
			emit_signal("workflow_end_requested", true) # Or some error state
	else:
		# next_ui_node is null, meaning workflow ends with confirmation
		emit_signal("workflow_end_requested", true)

func go_back():
	var target_path_to_try = back_ui_node_path
	if target_path_to_try.is_empty() and not parent_page_node_path.is_empty():
		target_path_to_try = parent_page_node_path

	if not target_path_to_try.is_empty():
		var target_node = get_node_or_null(target_path_to_try)
		if target_node and target_node is Control: # Ensure target_node is a Control, ideally a UIPage
			emit_signal("navigate_requested", target_node)
		else:
			printerr("Back/Parent UI node not found or not a Control: ", target_path_to_try, " from page ", name)
			emit_signal("workflow_end_requested", false) # Or some error state
	else:
		emit_signal("workflow_end_requested", false)

# --- Data Access Methods (Examples) ---
func get_main_data(key: String, default = null):
	if main_controller:
		return main_controller.get_shared_data(key, default)
	else: # <--- 修改点: 将警告移入 else 分支
		push_warning("Cannot get_main_data, Main controller not found from page '", name, "'")
		return default

func set_main_data(key: String, value):
	if main_controller:
		main_controller.set_shared_data(key, value)
	else: # <--- 修改点: 将警告移入 else 分支
		push_warning("Cannot set_main_data, Main controller not found from page '", name, "'. Data not set.")

# --- Helper function to check if potential_ancestor is an ancestor of node_to_check ---
func _is_ancestor_of(potential_ancestor: Node, node_to_check: Node) -> bool:
	if not potential_ancestor or not node_to_check:
		return false
	# Ensure both nodes are in the scene tree to safely use get_parent()
	if not node_to_check.is_inside_tree() or not potential_ancestor.is_inside_tree():
		return false
		
	var current_parent = node_to_check.get_parent()
	while current_parent:
		if current_parent == potential_ancestor:
			return true
		current_parent = current_parent.get_parent() # Move up the tree
	return false

# --- Helper for navigating to a specific child page (MODIFIED) ---
func go_to_child_page(child_page_node: Control):
	# Check if a child_page_node was provided
	if not child_page_node:
		printerr("Error in '", name, ".go_to_child_page': Target child_page_node is null.")
		return

	# This check prevents navigating to an ancestor using this function.
	# If child_page_node is an ancestor of self, it's considered an invalid target for "go_to_child_page".
	# Original problematic line: if child_page_node and child_page_node.is_a_parent_of(self):
	if _is_ancestor_of(child_page_node, self):
		printerr("Error in '", name, ".go_to_child_page': Navigation target '", child_page_node.name, 
				 "' cannot be an ancestor of the current page '", self.name, 
				 "'. 'go_to_child_page' is intended for pages that are descendants or unrelated in the scene tree hierarchy.")
		return

	# Optional: If 'go_to_child_page' strictly means a *direct child* in the scene tree,
	# you might want to add a check like this:
	# if child_page_node.get_parent() != self:
	#	printerr("Error in '", name, ".go_to_child_page': Target '", child_page_node.name,
	#			 "' is not a direct child of this page '", self.name, "'.")
	#	return

	# Ensure child_page_node is a Control (already type-hinted, but good for safety)
	if child_page_node is Control:
		emit_signal("navigate_requested", child_page_node)
		#self._on_page_deactivated()
	else:
		# This case might occur if something other than a Control node is passed,
		# despite the type hint.
		printerr("Error in '", name, ".go_to_child_page': Invalid target '", child_page_node, 
				 "'. It is not a Control node.")
