extends Node3D

## Main - Root scene that coordinates the game

# Components
var table_setup: TableSetup
var game_ui: GameUI
var hand_display: HandDisplay
var hand_layer: CanvasLayer
var action_log: ActionLog

# Player damage displays
var damage_displays: Array[DamageDisplay] = []

func _ready() -> void:
	_setup_table()
	_setup_ui()
	_connect_signals()

	# Start game when ready
	if GameManager.is_initialized:
		_start_game()
	else:
		GameManager.game_ready.connect(_start_game)

func _setup_table() -> void:
	table_setup = TableSetup.new()
	add_child(table_setup)

	# Connect table signals
	table_setup.card_clicked.connect(_on_table_card_clicked)

func _setup_ui() -> void:
	# Main game UI overlay (has its own CanvasLayer)
	game_ui = GameUI.new()
	game_ui.layer = 10  # Base UI layer
	add_child(game_ui)

	# Action log (collapsible panel on right side)
	var log_layer = CanvasLayer.new()
	log_layer.layer = 12  # Above other UI
	add_child(log_layer)

	action_log = ActionLog.new()
	log_layer.add_child(action_log)
	# Position on right side of screen
	action_log.set_anchors_preset(Control.PRESET_CENTER_RIGHT)
	action_log.offset_left = -290
	action_log.offset_right = -10
	action_log.offset_top = -200
	action_log.offset_bottom = 200

	# Connect undo signal
	action_log.undo_requested.connect(_on_undo_requested)

	# Connect to GameManager undo signals
	GameManager.undo_available_changed.connect(_on_undo_available_changed)

	# Ensure ActionLog connects to GameManager after it's in the tree
	action_log.call_deferred("_connect_game_manager_signals")

	# Hand display needs its own CanvasLayer to render on top of 3D
	hand_layer = CanvasLayer.new()
	hand_layer.layer = 11  # Above the game UI
	add_child(hand_layer)

	# Container for hand at bottom of screen - must fill the viewport
	var hand_container = Control.new()
	hand_layer.add_child(hand_container)
	hand_container.set_anchors_preset(Control.PRESET_FULL_RECT)
	hand_container.mouse_filter = Control.MOUSE_FILTER_IGNORE

	# Hand display positioned at bottom - use explicit positioning
	hand_display = HandDisplay.new()
	hand_container.add_child(hand_display)

	# Position at bottom of screen with explicit coordinates
	# We'll update position in _process or use a deferred call after container is sized
	call_deferred("_position_hand_display")

	hand_display.card_selected.connect(_on_hand_card_selected)
	hand_display.card_hovered.connect(_on_hand_card_hovered)
	hand_display.card_unhovered.connect(_on_hand_card_unhovered)

	# Create damage displays (positioned by 3D camera overlay later)
	for i in range(2):
		var damage_display = DamageDisplay.new()
		damage_displays.append(damage_display)

func _position_hand_display() -> void:
	# Get viewport size and position hand at bottom
	var viewport = get_viewport()
	if viewport:
		var vp_size = viewport.get_visible_rect().size
		hand_display.position = Vector2(50, vp_size.y - 180)
		hand_display.size = Vector2(vp_size.x - 100, 170)

		# Connect to viewport size changed signal if not already connected
		if not viewport.size_changed.is_connected(_on_viewport_resized):
			viewport.size_changed.connect(_on_viewport_resized)

func _on_viewport_resized() -> void:
	# Reposition hand display when window resizes
	var viewport = get_viewport()
	if viewport and hand_display:
		var vp_size = viewport.get_visible_rect().size
		hand_display.position = Vector2(50, vp_size.y - 180)
		hand_display.size = Vector2(vp_size.x - 100, 170)

func _connect_signals() -> void:
	# GameManager signals
	GameManager.game_started.connect(_on_game_started)
	GameManager.game_ended.connect(_on_game_ended)
	GameManager.turn_changed.connect(_on_turn_changed)
	GameManager.phase_changed.connect(_on_phase_changed)
	GameManager.damage_dealt.connect(_on_damage_dealt)

func _start_game() -> void:
	GameManager.start_new_game()
	# Force an update of visuals after a frame to ensure everything is ready
	call_deferred("_force_initial_update")

func _force_initial_update() -> void:
	_sync_visuals()
	_update_hand_display()
	_update_cp_display()

func _on_game_started() -> void:
	_sync_visuals()
	_update_hand_display()

func _on_game_ended(winner_name: String) -> void:
	game_ui.show_message(winner_name + " wins the game!")

func _on_turn_changed(_player_name: String, _turn_number: int) -> void:
	_sync_visuals()
	_update_hand_display()
	_update_cp_display()

func _on_phase_changed(_phase_name: String) -> void:
	_update_playable_highlights()
	_update_cp_display()

func _on_damage_dealt(player_name: String, _amount: int) -> void:
	# Find player index
	if GameManager.game_state:
		for i in range(2):
			var player = GameManager.game_state.get_player(i)
			if player and player.player_name == player_name:
				if i < damage_displays.size():
					damage_displays[i].set_damage(player.damage_zone.get_count())

func _sync_visuals() -> void:
	if GameManager.game_state and table_setup:
		table_setup.sync_with_game_state(GameManager.game_state)

func _update_hand_display() -> void:
	if not GameManager.game_state:
		return

	# Show current player's hand
	var current_player = GameManager.get_current_player()
	if current_player:
		var cards = current_player.hand.get_cards()
		hand_display.update_hand(cards)

func _update_cp_display() -> void:
	if not GameManager.game_state:
		return

	var current_player = GameManager.get_current_player()
	if current_player:
		game_ui.update_cp_display(current_player.cp_pool)

func _update_playable_highlights() -> void:
	if not GameManager.game_state:
		return

	var phase = GameManager.get_current_phase()
	var player = GameManager.get_current_player()

	if not player:
		hand_display.clear_highlights()
		return

	match phase:
		Enums.TurnPhase.MAIN_1, Enums.TurnPhase.MAIN_2:
			# Highlight cards that can be played
			hand_display.highlight_playable(func(card: CardInstance) -> bool:
				return player.cp_pool.can_afford_card(card.card_data)
			)
		_:
			hand_display.clear_highlights()

func _on_hand_card_selected(card: CardInstance) -> void:
	var input_mode = GameManager.input_mode

	match input_mode:
		GameManager.InputMode.SELECT_CARD_TO_PLAY:
			GameManager.try_play_card(card)
			_sync_visuals()
			_update_hand_display()
			_update_cp_display()

		GameManager.InputMode.SELECT_CP_SOURCE:
			# Discard for CP
			GameManager.discard_card_for_cp(card)
			_update_hand_display()
			_update_cp_display()

func _on_hand_card_hovered(card: CardInstance) -> void:
	game_ui.show_card_detail(card)

func _on_hand_card_unhovered() -> void:
	game_ui.hide_card_detail()

func _on_undo_requested() -> void:
	if GameManager.undo_last_action():
		_sync_visuals()
		_update_hand_display()
		_update_cp_display()
		_update_playable_highlights()
		# Restore input mode based on current phase
		GameManager.restore_input_mode_for_phase()

func _on_undo_available_changed(available: bool) -> void:
	if action_log:
		action_log.set_undo_available(available)

func _on_table_card_clicked(card: CardInstance, zone_type: Enums.ZoneType, player_index: int) -> void:
	var input_mode = GameManager.input_mode

	match input_mode:
		GameManager.InputMode.SELECT_CP_SOURCE:
			# Check if it's a backup we can dull
			if zone_type == Enums.ZoneType.FIELD_BACKUPS:
				if player_index == GameManager.game_state.turn_manager.current_player_index:
					GameManager.dull_backup_for_cp(card)
					_sync_visuals()
					_update_cp_display()

		GameManager.InputMode.SELECT_ATTACKER:
			# Select attacker
			if zone_type == Enums.ZoneType.FIELD_FORWARDS:
				if player_index == GameManager.game_state.turn_manager.current_player_index:
					GameManager.declare_attack(card)
					_sync_visuals()

		GameManager.InputMode.SELECT_BLOCKER:
			# Select blocker
			if zone_type == Enums.ZoneType.FIELD_FORWARDS:
				var opponent_index = 1 - GameManager.game_state.turn_manager.current_player_index
				if player_index == opponent_index:
					GameManager.declare_block(card)
					_sync_visuals()

	# Show card detail on any click
	game_ui.show_card_detail(card)

func _input(event: InputEvent) -> void:
	# Keyboard shortcuts
	if event is InputEventKey and event.pressed:
		# Ctrl+Z for undo
		if event.keycode == KEY_Z and event.ctrl_pressed:
			_on_undo_requested()
			return

		# L key to toggle action log
		if event.keycode == KEY_L and not event.ctrl_pressed:
			if action_log:
				action_log.toggle_panel()
			return

		match event.keycode:
			KEY_SPACE:
				# Pass priority / end phase
				GameManager.pass_priority()
				_sync_visuals()
				_update_hand_display()
				_update_cp_display()
			KEY_ESCAPE:
				# Cancel current selection
				GameManager.clear_selection()
				table_setup.clear_all_highlights()
				hand_display.clear_highlights()
