class_name ActionLog
extends Control

## ActionLog - Collapsible panel showing game actions

signal undo_requested

# UI Components
var panel: PanelContainer
var toggle_button: Button
var scroll_container: ScrollContainer
var log_container: VBoxContainer
var undo_button: Button
var clear_button: Button

# State
var is_expanded: bool = true
var action_entries: Array[Control] = []

# Layout constants
const COLLAPSED_WIDTH: float = 40.0
const EXPANDED_WIDTH: float = 280.0
const PANEL_HEIGHT: float = 400.0

func _ready() -> void:
	_create_ui()
	_connect_signals()

func _create_ui() -> void:
	# Set up this control to anchor to right side
	set_anchors_preset(Control.PRESET_CENTER_RIGHT)
	custom_minimum_size = Vector2(EXPANDED_WIDTH, PANEL_HEIGHT)
	size = Vector2(EXPANDED_WIDTH, PANEL_HEIGHT)
	mouse_filter = Control.MOUSE_FILTER_IGNORE

	# Main horizontal container
	var hbox = HBoxContainer.new()
	add_child(hbox)
	hbox.set_anchors_preset(Control.PRESET_FULL_RECT)
	hbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	hbox.size_flags_vertical = Control.SIZE_EXPAND_FILL
	hbox.mouse_filter = Control.MOUSE_FILTER_IGNORE

	# Toggle button on the left edge
	toggle_button = Button.new()
	toggle_button.text = ">"
	toggle_button.custom_minimum_size = Vector2(30, 0)
	toggle_button.size_flags_vertical = Control.SIZE_EXPAND_FILL
	toggle_button.tooltip_text = "Toggle Action Log (L)"
	hbox.add_child(toggle_button)

	# Panel container for the log
	panel = PanelContainer.new()
	hbox.add_child(panel)
	panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	panel.size_flags_vertical = Control.SIZE_EXPAND_FILL

	var style = StyleBoxFlat.new()
	style.bg_color = Color(0.08, 0.08, 0.12, 0.95)
	style.border_color = Color(0.3, 0.3, 0.4)
	style.set_border_width_all(2)
	style.set_corner_radius_all(5)
	style.set_content_margin_all(8)
	panel.add_theme_stylebox_override("panel", style)

	# Panel content
	var panel_vbox = VBoxContainer.new()
	panel.add_child(panel_vbox)
	panel_vbox.add_theme_constant_override("separation", 5)

	# Header
	var header = HBoxContainer.new()
	panel_vbox.add_child(header)
	header.add_theme_constant_override("separation", 5)

	var title = Label.new()
	title.text = "Action Log"
	title.add_theme_font_size_override("font_size", 14)
	title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	header.add_child(title)

	# Undo button
	undo_button = Button.new()
	undo_button.text = "Undo"
	undo_button.custom_minimum_size = Vector2(50, 25)
	undo_button.add_theme_font_size_override("font_size", 11)
	undo_button.tooltip_text = "Undo last action (Ctrl+Z)"
	undo_button.disabled = true
	header.add_child(undo_button)

	# Clear button
	clear_button = Button.new()
	clear_button.text = "Clear"
	clear_button.custom_minimum_size = Vector2(45, 25)
	clear_button.add_theme_font_size_override("font_size", 11)
	header.add_child(clear_button)

	# Separator
	var separator = HSeparator.new()
	panel_vbox.add_child(separator)

	# Scroll container for log entries
	scroll_container = ScrollContainer.new()
	panel_vbox.add_child(scroll_container)
	scroll_container.size_flags_vertical = Control.SIZE_EXPAND_FILL
	scroll_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	scroll_container.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
	scroll_container.custom_minimum_size = Vector2(200, 250)

	# Log entries container
	log_container = VBoxContainer.new()
	scroll_container.add_child(log_container)
	log_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL
	log_container.size_flags_vertical = Control.SIZE_EXPAND_FILL
	log_container.add_theme_constant_override("separation", 3)

func _connect_signals() -> void:
	toggle_button.pressed.connect(_on_toggle_pressed)
	undo_button.pressed.connect(_on_undo_pressed)
	clear_button.pressed.connect(clear_log)

	# Defer GameManager connections to ensure it's ready
	call_deferred("_connect_game_manager_signals")

func _connect_game_manager_signals() -> void:
	# Connect to GameManager signals
	if GameManager:
		if not GameManager.message.is_connected(_on_game_message):
			GameManager.message.connect(_on_game_message)
		if not GameManager.card_played.is_connected(_on_card_played):
			GameManager.card_played.connect(_on_card_played)
		if not GameManager.turn_changed.is_connected(_on_turn_changed):
			GameManager.turn_changed.connect(_on_turn_changed)
		if not GameManager.phase_changed.is_connected(_on_phase_changed):
			GameManager.phase_changed.connect(_on_phase_changed)
		if not GameManager.damage_dealt.is_connected(_on_damage_dealt):
			GameManager.damage_dealt.connect(_on_damage_dealt)
		if not GameManager.action_undone.is_connected(_on_action_undone):
			GameManager.action_undone.connect(_on_action_undone)

func _on_toggle_pressed() -> void:
	toggle_panel()

func toggle_panel() -> void:
	is_expanded = not is_expanded
	panel.visible = is_expanded
	toggle_button.text = ">" if is_expanded else "<"

	if is_expanded:
		custom_minimum_size.x = EXPANDED_WIDTH
		size.x = EXPANDED_WIDTH
	else:
		custom_minimum_size.x = COLLAPSED_WIDTH
		size.x = COLLAPSED_WIDTH

func _on_undo_pressed() -> void:
	undo_requested.emit()

## Add a log entry with a specific type for styling
func add_entry(text: String, entry_type: String = "info") -> void:
	if not log_container:
		return

	var entry = _create_entry(text, entry_type)
	log_container.add_child(entry)
	action_entries.append(entry)

	# Keep log at reasonable size
	while action_entries.size() > 100:
		var old_entry = action_entries.pop_front()
		old_entry.queue_free()

	# Scroll to bottom after adding
	call_deferred("_scroll_to_bottom")

func _create_entry(text: String, entry_type: String) -> Control:
	var entry_panel = PanelContainer.new()

	var style = StyleBoxFlat.new()
	style.set_content_margin_all(4)
	style.set_corner_radius_all(3)

	# Color based on type
	match entry_type:
		"turn":
			style.bg_color = Color(0.2, 0.3, 0.4, 0.8)
		"phase":
			style.bg_color = Color(0.15, 0.25, 0.35, 0.6)
		"action":
			style.bg_color = Color(0.2, 0.2, 0.3, 0.7)
		"damage":
			style.bg_color = Color(0.4, 0.15, 0.15, 0.7)
		"card":
			style.bg_color = Color(0.15, 0.3, 0.2, 0.7)
		_:
			style.bg_color = Color(0.12, 0.12, 0.18, 0.5)

	entry_panel.add_theme_stylebox_override("panel", style)

	var label = Label.new()
	label.text = text
	label.add_theme_font_size_override("font_size", 11)
	label.autowrap_mode = TextServer.AUTOWRAP_WORD
	label.custom_minimum_size.x = 200
	entry_panel.add_child(label)

	return entry_panel

func _scroll_to_bottom() -> void:
	await get_tree().process_frame
	scroll_container.scroll_vertical = int(scroll_container.get_v_scroll_bar().max_value)

func clear_log() -> void:
	for entry in action_entries:
		entry.queue_free()
	action_entries.clear()

## Enable or disable undo button
func set_undo_available(available: bool) -> void:
	undo_button.disabled = not available

## Manually add a message (can be called from Main.gd if signal connection fails)
func log_message(text: String) -> void:
	_on_game_message(text)

## Manually log a turn change
func log_turn_change(player_name: String, turn_number: int) -> void:
	_on_turn_changed(player_name, turn_number)

## Manually log a phase change
func log_phase_change(phase_name: String) -> void:
	_on_phase_changed(phase_name)

## Signal handlers
func _on_game_message(text: String) -> void:
	# Determine entry type based on message content
	var entry_type = "info"
	if "attacks" in text or "blocks" in text:
		entry_type = "action"
	elif "damage" in text or "broken" in text:
		entry_type = "damage"
	elif "Played" in text or "Discarded" in text or "Dulled" in text:
		entry_type = "card"

	add_entry(text, entry_type)

func _on_card_played(_card_data: Dictionary) -> void:
	# Already handled by message signal
	pass

func _on_turn_changed(player_name: String, turn_number: int) -> void:
	add_entry("=== " + player_name + " - Turn " + str(turn_number) + " ===", "turn")

func _on_phase_changed(phase_name: String) -> void:
	add_entry(phase_name, "phase")

func _on_damage_dealt(_player_name: String, _amount: int) -> void:
	# Already handled by message signal
	pass

func _on_action_undone(action_name: String) -> void:
	add_entry("UNDO: " + action_name, "action")

# Input is handled by Main.gd to avoid duplicate handling
