class_name BuildDrawer extends CanvasLayer
## Phase 17 — Build drawer bottom-sheet.
##
## A mobile-first panel for issuing Designation orders and queuing build jobs.
## Closed state: a 40×40 "+" button at bottom-right (always visible).
## Open state:   a full-width panel ~600 px tall with four tabs:
##               Designate | Build | Stockpile | Cancel
##
## Tapping any tool button calls Designation.set_active_tool(), emits
## EventBus.alert_added(&"info", …) and auto-closes the drawer so the player
## can begin painting tiles immediately.
##
## Layer 16 — above storyteller banner (15), below modal (20).

# ── layout constants ─────────────────────────────────────────────────────────
const LAYER_ORDER: int = 16
const PANEL_HEIGHT: int = 600
const BTN_SIZE: int = 80      # preferred hit area for build buttons
const FAB_SIZE: int = 48      # floating action button (open trigger)
const TAB_HEIGHT: int = 48
const LABEL_HEIGHT: int = 20
const FLOW_COLS: int = 4      # buttons per row in the flow grid

# ── tab indices ──────────────────────────────────────────────────────────────
const TAB_DESIGNATE: int = 0
const TAB_BUILD:     int = 1
const TAB_STOCKPILE: int = 2
const TAB_CANCEL:    int = 3

# ── state ────────────────────────────────────────────────────────────────────
var _open: bool = false
var _active_tab: int = TAB_DESIGNATE

# ── node refs (built at runtime) ─────────────────────────────────────────────
var _fab: Button = null          # floating ⊕ button (always visible)
var _panel: PanelContainer = null
var _close_btn: Button = null
var _tab_btns: Array[Button] = []
var _tab_containers: Array[Control] = []

# ── build-wall material chooser state ────────────────────────────────────────
# When the player first taps the Stone/Wood Wall button we show an inline
# material row; a second tap on the same button commits the choice.
var _wall_pending_mat: StringName = &""
var _floor_pending_mat: StringName = &""
var _wall_mat_row: HBoxContainer = null
var _floor_mat_row: HBoxContainer = null

## Injected by main.gd; the shared Designation controller on the World node.
var designation: Designation = null


func _ready() -> void:
	layer = LAYER_ORDER
	_build_ui()
	_set_panel_visible(false)
	Audit.log("build_drawer", "BuildDrawer ready (layer %d)" % layer)


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

func open() -> void:
	_set_panel_visible(true)
	Audit.log("build_drawer", "opened (tab=%d)" % _active_tab)


func close() -> void:
	_set_panel_visible(false)
	Audit.log("build_drawer", "closed")


func toggle() -> void:
	if _open:
		close()
	else:
		open()


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

func _build_ui() -> void:
	# Root control — full viewport anchor so anchors on children work.
	var root := Control.new()
	root.name = "Root"
	root.set_anchors_preset(Control.PRESET_FULL_RECT)
	root.mouse_filter = Control.MOUSE_FILTER_IGNORE
	add_child(root)

	# Floating action button — bottom-right, always visible.
	_fab = Button.new()
	_fab.name = "FAB"
	_fab.text = "+"
	_fab.custom_minimum_size = Vector2(FAB_SIZE, FAB_SIZE)
	_fab.focus_mode = Control.FOCUS_NONE
	_fab.set_anchors_preset(Control.PRESET_BOTTOM_RIGHT)
	_fab.offset_left  = -FAB_SIZE - 8
	_fab.offset_right = -8
	_fab.offset_top   = -FAB_SIZE - 8
	_fab.offset_bottom = -8
	_fab.pressed.connect(toggle)
	root.add_child(_fab)

	# Panel — full-width, anchored to the bottom of the screen.
	_panel = PanelContainer.new()
	_panel.name = "BuildPanel"
	_panel.set_anchors_preset(Control.PRESET_BOTTOM_WIDE)
	_panel.offset_top = -PANEL_HEIGHT
	_panel.offset_bottom = 0
	root.add_child(_panel)

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

	# ── header row (tabs + close button) ────────────────────────────────────
	var header := HBoxContainer.new()
	header.name = "Header"
	header.custom_minimum_size = Vector2(0, TAB_HEIGHT)
	header.add_theme_constant_override("separation", 2)
	vbox.add_child(header)

	var tab_names: Array[StringName] = [
		&"ui.build_drawer.designate",
		&"ui.build_drawer.build",
		&"ui.build_drawer.stockpile",
		&"ui.build_drawer.cancel",
	]
	_tab_btns.clear()
	for i in tab_names.size():
		var tb := Button.new()
		tb.text = Strings.t(tab_names[i])
		tb.custom_minimum_size = Vector2(0, TAB_HEIGHT)
		tb.focus_mode = Control.FOCUS_NONE
		tb.size_flags_horizontal = Control.SIZE_EXPAND_FILL
		var idx := i  # capture for closure
		tb.pressed.connect(func() -> void: _select_tab(idx))
		header.add_child(tb)
		_tab_btns.append(tb)

	_close_btn = Button.new()
	_close_btn.name = "CloseBtn"
	_close_btn.text = "X"
	_close_btn.custom_minimum_size = Vector2(TAB_HEIGHT, TAB_HEIGHT)
	_close_btn.focus_mode = Control.FOCUS_NONE
	_close_btn.pressed.connect(close)
	header.add_child(_close_btn)

	# ── scroll area for tab content ──────────────────────────────────────────
	var scroll := ScrollContainer.new()
	scroll.name = "Scroll"
	scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
	scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
	vbox.add_child(scroll)

	var content_stack := HBoxContainer.new()
	content_stack.name = "ContentStack"
	content_stack.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	# We only show one tab at a time by hiding the others.
	scroll.add_child(content_stack)

	# Build each tab panel.
	_tab_containers.clear()
	_tab_containers.append(_build_designate_tab())
	_tab_containers.append(_build_build_tab())
	_tab_containers.append(_build_stockpile_tab())
	_tab_containers.append(_build_cancel_tab())

	for tc in _tab_containers:
		tc.size_flags_horizontal = Control.SIZE_EXPAND_FILL
		content_stack.add_child(tc)

	_select_tab(TAB_DESIGNATE)


func _build_designate_tab() -> Control:
	var box := VBoxContainer.new()
	box.name = "DesignateTab"
	box.add_theme_constant_override("separation", 8)

	var flow := _make_flow_grid()
	box.add_child(flow)

	_add_tool_btn(flow, Strings.t(&"tool.chop"),     Color(0.3, 0.7, 0.2), func() -> void: _activate(&"chop",    &"",       Strings.t(&"tool.chop")))
	_add_tool_btn(flow, Strings.t(&"tool.mine"),     Color(0.6, 0.6, 0.6), func() -> void: _activate(&"mine",    &"",       Strings.t(&"tool.mine")))
	_add_tool_btn(flow, Strings.t(&"tool.dig_grave"),Color(0.4, 0.3, 0.2), func() -> void: _activate(&"dig_grave",&"",      Strings.t(&"tool.dig_grave")))
	_add_tool_btn(flow, Strings.t(&"tool.no_roof"),  Color(0.7, 0.7, 0.9), func() -> void: _activate(&"no_roof", &"",      Strings.t(&"tool.no_roof")))

	return box


func _build_build_tab() -> Control:
	var box := VBoxContainer.new()
	box.name = "BuildTab"
	box.add_theme_constant_override("separation", 8)

	var flow := _make_flow_grid()
	box.add_child(flow)

	# Wall — show material chooser on first tap.
	_add_tool_btn(flow, Strings.t(&"tool.build_wall_stone"), Color(0.55, 0.55, 0.55),
		func() -> void: _activate_wall(&"stone"))
	_add_tool_btn(flow, Strings.t(&"tool.build_wall_wood"),  Color(0.65, 0.45, 0.25),
		func() -> void: _activate_wall(&"wood"))

	# Floor.
	_add_tool_btn(flow, Strings.t(&"tool.build_floor_wood"),  Color(0.60, 0.40, 0.20),
		func() -> void: _activate_floor(&"wood"))
	_add_tool_btn(flow, Strings.t(&"tool.build_floor_stone"), Color(0.60, 0.60, 0.55),
		func() -> void: _activate_floor(&"stone"))

	# Door + Crate.
	_add_tool_btn(flow, Strings.t(&"tool.build_door"),  Color(0.55, 0.35, 0.15),
		func() -> void: _activate(&"build_door",  &"", Strings.t(&"tool.build_door")))
	_add_tool_btn(flow, Strings.t(&"tool.build_crate"), Color(0.65, 0.45, 0.10),
		func() -> void: _activate(&"build_crate", &"", Strings.t(&"tool.build_crate")))

	# Bed + Torch.
	_add_tool_btn(flow, Strings.t(&"tool.build_bed"),   Color(0.40, 0.40, 0.80),
		func() -> void: _activate(&"build_bed",   &"", Strings.t(&"tool.build_bed")))
	_add_tool_btn(flow, Strings.t(&"tool.build_torch"), Color(0.90, 0.70, 0.20),
		func() -> void: _activate(&"build_torch", &"", Strings.t(&"tool.build_torch")))

	# Workbenches.
	_add_tool_btn(flow, Strings.t(&"tool.workbench_carpenter"),
		Color(0.50, 0.35, 0.15),
		func() -> void: _activate(&"build_workbench_carpenter",  &"", Strings.t(&"tool.workbench_carpenter")))
	_add_tool_btn(flow, Strings.t(&"tool.workbench_smelter"),
		Color(0.60, 0.55, 0.45),
		func() -> void: _activate(&"build_workbench_smelter",    &"", Strings.t(&"tool.workbench_smelter")))
	_add_tool_btn(flow, Strings.t(&"tool.workbench_millstone"),
		Color(0.55, 0.55, 0.55),
		func() -> void: _activate(&"build_workbench_millstone",  &"", Strings.t(&"tool.workbench_millstone")))
	_add_tool_btn(flow, Strings.t(&"tool.workbench_hearth"),
		Color(0.80, 0.35, 0.15),
		func() -> void: _activate(&"build_workbench_hearth",     &"", Strings.t(&"tool.workbench_hearth")))
	_add_tool_btn(flow, Strings.t(&"tool.workbench_cremation_pyre"),
		Color(0.30, 0.25, 0.20),
		func() -> void: _activate(&"build_workbench_cremation_pyre", &"", Strings.t(&"tool.workbench_cremation_pyre")))

	return box


func _build_stockpile_tab() -> Control:
	var box := VBoxContainer.new()
	box.name = "StockpileTab"
	box.add_theme_constant_override("separation", 8)

	var flow := _make_flow_grid()
	box.add_child(flow)

	_add_tool_btn(flow, Strings.t(&"tool.stockpile_general"), Color(0.30, 0.60, 0.30),
		func() -> void: _activate(&"paint_stockpile", &"", Strings.t(&"tool.stockpile_general")))
	_add_tool_btn(flow, Strings.t(&"tool.graveyard"),         Color(0.25, 0.20, 0.15),
		func() -> void: _activate(&"graveyard",        &"", Strings.t(&"tool.graveyard")))

	return box


func _build_cancel_tab() -> Control:
	var box := VBoxContainer.new()
	box.name = "CancelTab"
	box.add_theme_constant_override("separation", 8)

	var lbl := Label.new()
	lbl.text = Strings.t(&"ui.build_drawer.cancel")
	lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
	lbl.add_theme_constant_override("margin_top", 16)
	box.add_child(lbl)

	var btn := Button.new()
	btn.text = Strings.t(&"ui.cancel")
	btn.custom_minimum_size = Vector2(200, BTN_SIZE)
	btn.focus_mode = Control.FOCUS_NONE
	var cancel_hbox := HBoxContainer.new()
	cancel_hbox.alignment = BoxContainer.ALIGNMENT_CENTER
	cancel_hbox.add_child(btn)
	box.add_child(cancel_hbox)

	btn.pressed.connect(_on_cancel_pressed)

	return box


# ── helpers — UI factories ───────────────────────────────────────────────────

func _make_flow_grid() -> GridContainer:
	var g := GridContainer.new()
	g.columns = FLOW_COLS
	g.add_theme_constant_override("h_separation", 8)
	g.add_theme_constant_override("v_separation", 8)
	return g


## Add a single tool button to `container`. Each button is a VBoxContainer of
## [ColorRect icon area + Label] wrapped in a Button so the whole cell is one
## touch target.
func _add_tool_btn(container: Control, label_text: String, icon_color: Color, callback: Callable) -> void:
	var btn := Button.new()
	btn.custom_minimum_size = Vector2(BTN_SIZE, BTN_SIZE + LABEL_HEIGHT)
	btn.focus_mode = Control.FOCUS_NONE

	var vb := VBoxContainer.new()
	vb.mouse_filter = Control.MOUSE_FILTER_IGNORE
	vb.add_theme_constant_override("separation", 2)

	# Icon area — procedural colored rect (real sprites land with Phase 17 art pass).
	var icon := ColorRect.new()
	icon.color = icon_color
	icon.custom_minimum_size = Vector2(BTN_SIZE - 8, BTN_SIZE - LABEL_HEIGHT - 8)
	icon.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
	icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
	vb.add_child(icon)

	# Label.
	var lbl := Label.new()
	lbl.text = label_text
	lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
	lbl.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
	lbl.custom_minimum_size = Vector2(BTN_SIZE, LABEL_HEIGHT)
	lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE
	vb.add_child(lbl)

	btn.add_child(vb)
	btn.pressed.connect(callback)
	container.add_child(btn)


# ── helpers — tab switching ──────────────────────────────────────────────────

func _select_tab(idx: int) -> void:
	_active_tab = idx
	for i in _tab_containers.size():
		_tab_containers[i].visible = (i == idx)
	for i in _tab_btns.size():
		_tab_btns[i].modulate = Color(1.2, 1.2, 0.8) if i == idx else Color.WHITE


# ── helpers — tool activation ────────────────────────────────────────────────

## Activate `tool_id`, optionally set `mat` on the Designation controller, emit
## the alert feedback, and auto-close the drawer.
func _activate(tool_id: StringName, mat: StringName, display_name: String) -> void:
	if designation == null:
		Audit.log("build_drawer", "no Designation ref — cannot activate tool '%s'" % tool_id)
		return
	designation.tool_material = mat
	designation.set_active_tool(tool_id)
	EventBus.alert_added.emit(&"info", "Tool: %s" % display_name, Vector2i(-1, -1))
	close()
	Audit.log("build_drawer", "activated tool '%s' (mat='%s')" % [tool_id, mat])


func _activate_wall(mat: StringName) -> void:
	var display: String = Strings.t(&"tool.build_wall_stone") if mat == &"stone" \
		else Strings.t(&"tool.build_wall_wood")
	_activate(&"build_wall", mat, display)


func _activate_floor(mat: StringName) -> void:
	var display: String = Strings.t(&"tool.build_floor_wood") if mat == &"wood" \
		else Strings.t(&"tool.build_floor_stone")
	_activate(&"build_floor", mat, display)


func _on_cancel_pressed() -> void:
	if designation != null:
		designation.tool_material = &""
		designation.set_active_tool(Designation.TOOL_NONE)
		EventBus.alert_added.emit(&"info", "Tool: None", Vector2i(-1, -1))
	close()
	Audit.log("build_drawer", "tool cancelled")


# ── keyboard input ───────────────────────────────────────────────────────────

func _unhandled_input(event: InputEvent) -> void:
	# B — toggle the build drawer.
	if event.is_action_pressed("open_build"):
		toggle()
		get_viewport().set_input_as_handled()
		return
	# Escape — close if open (panel Escape runs before Selection deselect).
	if event.is_action_pressed("cancel") and _open:
		close()
		get_viewport().set_input_as_handled()
		return


# ── helpers — visibility ─────────────────────────────────────────────────────

func _set_panel_visible(v: bool) -> void:
	_open = v
	if _panel != null:
		_panel.visible = v
	# Keep the FAB visible at all times.
