class_name HelpModal extends CanvasLayer
## Phase 19 — Static reference modal opened via Settings → Help button.
##
## Layer 20 (same as StorytellerModal — mutually exclusive in practice; the
## Settings menu sits above both and dims the world before Help opens).
##
## Five sections: Controls / Verbs / Priorities / Storyteller / Tips.
## Tab row across the top of the content area; active tab tinted amber.
## ScrollContainer per-section so long copy doesn't overflow.
##
## Opened by EventBus.help_requested signal (emitted by SettingsMenu).
## Closed by: X button, tapping the dim backdrop, or Escape.
##
## CanvasLayer.visible is toggled (not just inner Control) so the dim
## MOUSE_FILTER_STOP backing doesn't eat world input when the modal is hidden.
## PROCESS_MODE_ALWAYS so it remains accessible while the sim is paused.

const LAYER_ORDER: int = 20
const MODAL_W: int = 720
const MODAL_H: int = 560
const TAB_COUNT: int = 5
const AMBER: Color = Color(1.0, 0.75, 0.2, 1.0)

# ── tab indices ──────────────────────────────────────────────────────────────
const TAB_CONTROLS:    int = 0
const TAB_VERBS:       int = 1
const TAB_PRIORITIES:  int = 2
const TAB_STORYTELLER: int = 3
const TAB_TIPS:        int = 4

# ── state ────────────────────────────────────────────────────────────────────
var _active_tab: int = TAB_CONTROLS

# ── node refs ────────────────────────────────────────────────────────────────
var _dim: ColorRect = null
var _panel: PanelContainer = null
var _tab_btns: Array[Button] = []
var _scroll: ScrollContainer = null
var _content_box: VBoxContainer = null


func _ready() -> void:
	layer = LAYER_ORDER
	process_mode = Node.PROCESS_MODE_ALWAYS
	_build_ui()
	_set_visible(false)
	EventBus.help_requested.connect(_on_help_requested)
	Audit.log("help_modal", "HelpModal ready (layer %d)" % layer)


func _exit_tree() -> void:
	if EventBus.help_requested.is_connected(_on_help_requested):
		EventBus.help_requested.disconnect(_on_help_requested)


# ── public API ────────────────────────────────────────────────────────────────

func open() -> void:
	_active_tab = TAB_CONTROLS
	_set_visible(true)
	_refresh_tabs()
	call_deferred("_show_section")
	Audit.log("help_modal", "opened")


func close() -> void:
	_set_visible(false)
	Audit.log("help_modal", "closed")


# ── UI construction ───────────────────────────────────────────────────────────

func _build_ui() -> void:
	# Dim backdrop — MOUSE_FILTER_STOP so click-outside dismisses.
	_dim = ColorRect.new()
	_dim.name = "Dim"
	_dim.set_anchors_preset(Control.PRESET_FULL_RECT)
	_dim.color = Color(0.0, 0.0, 0.0, 0.55)
	_dim.mouse_filter = Control.MOUSE_FILTER_STOP
	_dim.gui_input.connect(_on_dim_input)
	add_child(_dim)

	# Centered modal panel.
	_panel = PanelContainer.new()
	_panel.name = "HelpDialog"
	_panel.set_anchors_preset(Control.PRESET_CENTER)
	_panel.custom_minimum_size = Vector2(MODAL_W, MODAL_H)
	_panel.offset_left   = -MODAL_W / 2
	_panel.offset_right  =  MODAL_W / 2
	_panel.offset_top    = -MODAL_H / 2
	_panel.offset_bottom =  MODAL_H / 2
	add_child(_panel)

	var outer := VBoxContainer.new()
	outer.add_theme_constant_override("separation", 0)
	_panel.add_child(outer)

	# ── Header row: title label + close button ────────────────────────────────
	var header := HBoxContainer.new()
	header.name = "Header"
	header.add_theme_constant_override("separation", 8)
	header.custom_minimum_size = Vector2(0, 48)
	outer.add_child(header)

	var title_lbl := Label.new()
	title_lbl.name = "Title"
	title_lbl.text = Strings.t(&"ui.help.title")
	title_lbl.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	title_lbl.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
	title_lbl.add_theme_font_size_override("font_size", 22)
	header.add_child(title_lbl)

	var close_btn := Button.new()
	close_btn.name = "CloseBtn"
	close_btn.text = Strings.t(&"ui.help.close")
	close_btn.custom_minimum_size = Vector2(48, 48)
	close_btn.focus_mode = Control.FOCUS_NONE
	close_btn.pressed.connect(close)
	header.add_child(close_btn)

	outer.add_child(HSeparator.new())

	# ── Tab row ───────────────────────────────────────────────────────────────
	var tab_row := HBoxContainer.new()
	tab_row.name = "TabRow"
	tab_row.add_theme_constant_override("separation", 4)
	outer.add_child(tab_row)

	var tab_keys: Array[StringName] = [
		&"ui.help.tab.controls",
		&"ui.help.tab.verbs",
		&"ui.help.tab.priorities",
		&"ui.help.tab.storyteller",
		&"ui.help.tab.tips",
	]

	_tab_btns.clear()
	for i in range(TAB_COUNT):
		var btn := Button.new()
		btn.name = "Tab%d" % i
		btn.text = Strings.t(tab_keys[i])
		btn.custom_minimum_size = Vector2(0, 36)
		btn.size_flags_horizontal = Control.SIZE_EXPAND_FILL
		btn.focus_mode = Control.FOCUS_NONE
		var idx: int = i  # capture for lambda
		btn.pressed.connect(func() -> void: _on_tab_pressed(idx))
		tab_row.add_child(btn)
		_tab_btns.append(btn)

	outer.add_child(HSeparator.new())

	# ── Scrollable content area ───────────────────────────────────────────────
	_scroll = ScrollContainer.new()
	_scroll.name = "ContentScroll"
	_scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
	_scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
	outer.add_child(_scroll)

	_content_box = VBoxContainer.new()
	_content_box.name = "ContentBox"
	_content_box.add_theme_constant_override("separation", 8)
	_content_box.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	_scroll.add_child(_content_box)


# ── tab switching ─────────────────────────────────────────────────────────────

func _on_tab_pressed(idx: int) -> void:
	_active_tab = idx
	_refresh_tabs()
	call_deferred("_show_section")


func _refresh_tabs() -> void:
	for i in range(_tab_btns.size()):
		if i == _active_tab:
			_tab_btns[i].modulate = AMBER
		else:
			_tab_btns[i].modulate = Color.WHITE


func _show_section() -> void:
	# Clear old content.
	for child in _content_box.get_children():
		child.queue_free()

	# Reset scroll position.
	_scroll.scroll_vertical = 0

	var heading: String
	var body: String

	match _active_tab:
		TAB_CONTROLS:
			heading = Strings.t(&"help.controls.heading")
			body    = Strings.t(&"help.controls.body")
		TAB_VERBS:
			heading = Strings.t(&"help.verbs.heading")
			body    = Strings.t(&"help.verbs.body")
		TAB_PRIORITIES:
			heading = Strings.t(&"help.priorities.heading")
			body    = Strings.t(&"help.priorities.body")
		TAB_STORYTELLER:
			heading = Strings.t(&"help.storyteller.heading")
			body    = Strings.t(&"help.storyteller.body")
		TAB_TIPS:
			heading = Strings.t(&"help.tips.heading")
			body    = Strings.t(&"help.tips.body")
		_:
			heading = ""
			body    = ""

	var heading_lbl := Label.new()
	heading_lbl.name = "SectionHeading"
	heading_lbl.text = heading
	heading_lbl.add_theme_font_size_override("font_size", 16)
	_content_box.add_child(heading_lbl)

	_content_box.add_child(HSeparator.new())

	var body_lbl := Label.new()
	body_lbl.name = "SectionBody"
	body_lbl.text = body
	body_lbl.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
	body_lbl.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	_content_box.add_child(body_lbl)


# ── input handling ────────────────────────────────────────────────────────────

func _unhandled_input(event: InputEvent) -> void:
	if not visible:
		return
	if event.is_action_pressed("cancel"):
		close()
		get_viewport().set_input_as_handled()


func _on_dim_input(event: InputEvent) -> void:
	# Clicking the dim backdrop closes the modal.
	if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
		close()


# ── signal handler ────────────────────────────────────────────────────────────

func _on_help_requested() -> void:
	open()


# ── visibility ────────────────────────────────────────────────────────────────

func _set_visible(v: bool) -> void:
	# Toggle CanvasLayer.visible so the dim (MOUSE_FILTER_STOP) does not eat
	# world input when the modal is hidden.
	visible = v
	if _dim != null:
		_dim.visible = v
	if _panel != null:
		_panel.visible = v
