extends Control
class_name InventoryBackpack

signal overlay_show_requested
signal overlay_hide_requested
signal item_selected(item_id: String)
signal returning_to_idle
signal skip_action_requested

enum State { IDLE, OPEN, SELECTED, ACQUIRE, REMOVE }

var _state: State = State.IDLE
var _animating: bool = false
var _active_tween: Tween = null
var _floating_item_color: Color = Color(1, 1, 1, 0)
var _home_position: Vector2 = Vector2(0, 0)

@onready var backpack_icon: ColorRect = $BackpackIcon
@onready var floating_item: ColorRect = $FloatingItem
@onready var animation_player: AnimationPlayer = $AnimationPlayer

func _ready() -> void:
	_home_position = backpack_icon.position
	floating_item.modulate = Color(1, 1, 1, 0)
	floating_item.visible = false
	InventoryManager.item_acquired.connect(_on_item_acquired)
	InventoryManager.item_removed.connect(_on_item_removed)
	InventoryManager.inventory_changed.connect(_on_inventory_changed)
	_update_floating_item()

func get_state() -> State:
	return _state

func is_busy() -> bool:
	return _animating

func _update_floating_item() -> void:
	if InventoryManager.selected_item:
		var def = InventoryManager.get_item_definition(InventoryManager.selected_item)
		if def:
			floating_item.visible = true
			floating_item.modulate = Color(1, 0.6, 0.2, 1)
		else:
			floating_item.visible = true
			floating_item.modulate = Color(0.8, 0.8, 0.8, 1)
	else:
		floating_item.visible = false

func transition_to(new_state: State) -> void:
	if _animating and new_state != _state:
		_kill_tween()
	match new_state:
		State.IDLE:
			_transition_to_idle()
		State.OPEN:
			_transition_to_open()
		State.SELECTED:
			_transition_to_selected()
		State.ACQUIRE:
			_transition_to_acquire()
		State.REMOVE:
			_transition_to_remove()

func _transition_to_idle() -> void:
	if _state == State.IDLE:
		return
	_set_state(State.IDLE)
	overlay_hide_requested.emit()
	backpack_icon.modulate = Color(1, 1, 1, 1)
	floating_item.visible = false

	var tween = create_tween().bind_node(self)
	_active_tween = tween
	_animating = true
	tween.tween_property(backpack_icon, "rotation", 0.0, 0.35).set_trans(Tween.TRANS_LINEAR)
	tween.tween_property(backpack_icon, "position", _home_position, 0.35).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN)
	tween.tween_callback(_on_transition_complete.bind(State.IDLE))

func _transition_to_open() -> void:
	var can_open = _check_guards()
	if not can_open:
		if _state == State.IDLE:
			skip_action_requested.emit()
		return

	_set_state(State.OPEN)

	var tween = create_tween().bind_node(self)
	_active_tween = tween
	_animating = true
	tween.tween_property(backpack_icon, "rotation", PI / 4, 0.35).set_trans(Tween.TRANS_LINEAR)
	tween.tween_property(backpack_icon, "position", _home_position + Vector2(20, 20), 0.35).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN)
	tween.tween_callback(_on_transition_complete.bind(State.OPEN))
	tween.tween_callback(overlay_show_requested.emit)

func _transition_to_selected() -> void:
	if _state == State.SELECTED:
		return

	_set_state(State.SELECTED)
	_update_floating_item()

	var tween = create_tween().bind_node(self)
	_active_tween = tween
	_animating = true

	floating_item.visible = true
	floating_item.modulate = Color(1, 1, 1, 0)
	tween.tween_property(floating_item, "modulate", Color(1, 1, 1, 1), 0.5).set_trans(Tween.TRANS_LINEAR)
	tween.tween_callback(_on_transition_complete.bind(State.SELECTED))

func _transition_to_acquire() -> void:
	if _state == State.ACQUIRE or _state == State.REMOVE:
		_kill_tween()

	_set_state(State.ACQUIRE)

	var tween = create_tween().bind_node(self)
	_active_tween = tween
	_animating = true

	backpack_icon.modulate = Color(1, 1, 1, 1)
	tween.tween_property(backpack_icon, "rotation", PI / 4, 0.35).set_trans(Tween.TRANS_LINEAR)
	tween.tween_callback(_start_acquire_item_anim)

func _start_acquire_item_anim() -> void:
	var tween = create_tween().bind_node(self)
	_active_tween = tween

	floating_item.visible = true
	floating_item.modulate = Color(1, 1, 1, 0)
	floating_item.position = Vector2(backpack_icon.position.x - 20, backpack_icon.position.y - 40)

	tween.tween_property(floating_item, "modulate", Color(1, 1, 1, 1), 0.5).set_trans(Tween.TRANS_LINEAR)
	tween.tween_property(floating_item, "position", backpack_icon.position, 0.5).set_trans(Tween.TRANS_LINEAR)
	tween.tween_callback(_on_acquire_complete)

func _on_acquire_complete() -> void:
	floating_item.visible = false
	transition_to(State.IDLE)

func _transition_to_remove() -> void:
	if _state == State.ACQUIRE or _state == State.REMOVE:
		_kill_tween()

	_set_state(State.REMOVE)

	var tween = create_tween().bind_node(self)
	_active_tween = tween
	_animating = true

	backpack_icon.modulate = Color(1, 1, 1, 1)
	tween.tween_property(backpack_icon, "rotation", PI / 4, 0.35).set_trans(Tween.TRANS_LINEAR)
	tween.tween_callback(_start_remove_item_anim)

func _start_remove_item_anim() -> void:
	var tween = create_tween().bind_node(self)
	_active_tween = tween

	floating_item.visible = true
	floating_item.modulate = Color(1, 1, 1, 1)
	floating_item.position = backpack_icon.position

	tween.tween_property(floating_item, "position", Vector2(backpack_icon.position.x - 20, backpack_icon.position.y - 80), 0.5).set_trans(Tween.TRANS_LINEAR)
	tween.parallel().tween_property(floating_item, "modulate", Color(1, 1, 1, 0), 0.5).set_trans(Tween.TRANS_LINEAR)
	tween.tween_callback(_on_remove_complete)

func _on_remove_complete() -> void:
	floating_item.visible = false
	var was_selected = InventoryManager.selected_item != ""
	transition_to(State.IDLE)
	if was_selected:
		InventoryManager.clear_selection()

func _set_state(new_state: State) -> void:
	_state = new_state

func _check_guards() -> bool:
	var main_game = get_node_or_null("/root/Node2D")
	if not main_game:
		return true

	if main_game.is_script_running:
		return false

	var fade = get_node_or_null("/root/Node2D/SceneDisplay/Fade")
	if fade and fade.modulate.a > 0.5:
		return false

	return true

func _kill_tween() -> void:
	if _active_tween:
		_active_tween.kill()
		_active_tween = null
	_animating = false

func _on_transition_complete(completed_state: State) -> void:
	_animating = false
	_active_tween = null
	if completed_state == State.OPEN:
		pass
	elif completed_state == State.IDLE:
		returning_to_idle.emit()

func _on_item_acquired(item_id: String) -> void:
	if _state == State.IDLE:
		transition_to(State.ACQUIRE)

func _on_item_removed(item_id: String) -> void:
	if _state == State.IDLE:
		if InventoryManager.selected_item == item_id:
			InventoryManager.clear_selection()
			_update_floating_item()
			transition_to(State.REMOVE)
		else:
			transition_to(State.REMOVE)
	elif _state == State.SELECTED and InventoryManager.selected_item == item_id:
		InventoryManager.clear_selection()
		_update_floating_item()
		transition_to(State.REMOVE)

func _on_inventory_changed() -> void:
	_update_floating_item()

func _gui_input(event: InputEvent) -> void:
	
	if event is InputEventMouseButton and event.pressed and event.button_index == 1:
		print("OBTAINED")
		if _state == State.IDLE:
			transition_to(State.OPEN)
		elif _state == State.OPEN:
			transition_to(State.IDLE)

func _notification(what: int) -> void:
	if what == NOTIFICATION_PREDELETE:
		_kill_tween()
