class_name InventoryUI extends Control

signal item_focused(item: Option)
signal item_selected(item: Item)

@export var inventory: Inventory
@export var item_scene: PackedScene
@export var carousel: IndexCarousel

func _ready() -> void:
    inventory.updated.connect(_build_carousel)
    carousel.index_changed.connect(_on_item_changed)

func _items() -> Iterator:
    return inventory.iter().map(func(x): return x.value.item)

func _on_item_changed(index: int) -> void:
    match _items().nth(index):
        var x when x.is_some():
            item_focused.emit(Option.from(x.unwrap()))
        _: item_focused.emit(Option.none)

func _build_carousel() -> void:
    KCUtils.remove_children(carousel)

    var empty_iter = Iterator.repeat(null).take(inventory.empty_slots)
    var item_iter = ListIterator.from_array(inventory.items.values().map(func(x): return x.item))
    var items = FusedIterator.new([item_iter, empty_iter])

    for item in items:
        var scene = create_item()
        var option = Option.from(item)
        bind_item(scene, option)
        carousel.add_child(scene)

func create_item() -> Node:
    return item_scene.instantiate()

func bind_item(node: Node, item: Option) -> void:
    if node.has_method('bind'):
        node.bind(item)

func _gui_input(event: InputEvent) -> void:
    if event.is_action_pressed(PlayerInput.UIAction.Right):
        move_right()
    elif event.is_action_pressed(PlayerInput.UIAction.Left):
        move_left()
    elif event.is_action_pressed(PlayerInput.UIAction.Accept):
        var selected = _items().nth(carousel.current_index)
        if selected.is_some():
            item_selected.emit(selected.unwrap())

func move_by(delta: int):
    var next_index = carousel.get_carousel_index() + delta
    carousel.go_to_index(next_index)

func move_right():
    move_by(1)

func move_left():
    move_by(-1)
