class_name DialogueChoiceBox extends PanelContainer

const SCENE:PackedScene = preload("res://ui/component/DialogueChoiceBox.tscn")
const MAX_WIDTH:float = 120.0

signal chosen(response:DialogueResponse)

var _responses:Array[DialogueResponse] = []
var _entity:Entity = null
var _selectedIndex:int = 0
var _hasLetGoOfInteract:bool = true

@onready var _list:VBoxContainer = $VBoxContainer/List

func _ready() -> void:
  size.x = MAX_WIDTH
  visible = false

func setup(responses:Array[DialogueResponse], entity:Entity) -> void:
  _entity = entity
  _responses = responses.filter(func(r): return r.is_allowed)
  _selectedIndex = 0
  _hasLetGoOfInteract = !Input.is_action_pressed("interact")

  for child in _list.get_children():
    child.queue_free()

  for response in _responses:
    var label:Label = Label.new()
    label.text = response.text
    label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
    _list.add_child(label)

  size.x = MAX_WIDTH
  visible = true
  _updateSelection()

func _process(_delta:float) -> void:
  if not visible:
    return
  _updateWorldPosition()
  _processInput()

func _processInput() -> void:
  if Input.is_action_just_released("interact"):
    _hasLetGoOfInteract = true

  if Input.is_action_just_pressed("ui_up") or Input.is_action_just_pressed("move_forward"):
    _selectedIndex = max(0, _selectedIndex - 1)
    _updateSelection()

  if Input.is_action_just_pressed("ui_down") or Input.is_action_just_pressed("move_back"):
    _selectedIndex = min(_responses.size() - 1, _selectedIndex + 1)
    _updateSelection()

  if _hasLetGoOfInteract and Input.is_action_just_pressed("interact"):
    _confirm()

func _confirm() -> void:
  if _responses.is_empty():
    return
  var response:DialogueResponse = _responses[_selectedIndex]
  chosen.emit(response)
  visible = false
  queue_free()

func _updateSelection() -> void:
  var children:Array = _list.get_children()
  for i in children.size():
    var label:Label = children[i]
    if i == _selectedIndex:
      label.add_theme_color_override("font_color", Color.YELLOW)
    else:
      label.remove_theme_color_override("font_color")

func _updateWorldPosition() -> void:
  if _entity == null:
    return
  var camera:Camera3D = get_viewport().get_camera_3d()
  if camera == null:
    return
  var worldPos:Vector3 = _entity.global_position + Vector3(0, 2.5, 0)
  var screenPos:Vector2 = camera.unproject_position(worldPos)
  var viewportSize:Vector2 = get_viewport().get_visible_rect().size
  position = screenPos - Vector2(size.x * 0.5, size.y)
  position.x = clamp(position.x, 0.0, viewportSize.x - size.x)
  position.y = clamp(position.y, 0.0, viewportSize.y - size.y)
