extends Control
class_name InventoryOverlay

signal close_requested
signal item_confirmed(item_id: String)
signal combine_requested(item_a_id: String, item_b_id: String)
signal inspect_requested(item_id: String)

var input_active: bool = false
var _is_visible: bool = false
var _selected_slot: InventorySlot = null
var _drag_start_time: float = 0.0
var _is_dragging: bool = false
var _dragged_item: Control = null
var _hovered_slot: InventorySlot = null
var _fade_tween: Tween = null

const FADE_DURATION: float = 0.2
const LONG_PRESS_THRESHOLD: float = 0.5
const SLOTS_PER_ROW: int = 8
const SLOT_SIZE: Vector2i = Vector2i(64, 64)

@onready var background: ColorRect = $Background
@onready var panel: Control = $InventoryPanel
@onready var frame: ColorRect = $InventoryPanel/Frame
@onready var grid: GridContainer = $InventoryPanel/ItemGrid
@onready var hover_label: Label = $InventoryPanel/HoverLabel

func _ready() -> void:
	hide()
	background.mouse_filter = Control.MOUSE_FILTER_STOP
	InventoryManager.inventory_changed.connect(_refresh_grid)
	InventoryManager.combination_attempted.connect(_on_combination_attempted)

func show_overlay() -> void:
	_refresh_grid()
	if _fade_tween:
		_fade_tween.kill()
		_fade_tween = null

	_is_visible = true
	show()
	modulate = Color(1, 1, 1, 0)
	input_active = false

	var tween = create_tween().bind_node(self)
	_fade_tween = tween
	tween.tween_property(self, "modulate", Color(1, 1, 1, 1), FADE_DURATION)
	tween.tween_callback(_on_fade_in_complete)

func hide_overlay() -> void:
	if _fade_tween:
		_fade_tween.kill()
		_fade_tween = null

	input_active = false
	_clear_selection()

	var tween = create_tween().bind_node(self)
	_fade_tween = tween
	tween.tween_property(self, "modulate", Color(1, 1, 1, 0), FADE_DURATION)
	tween.tween_callback(_on_fade_out_complete)

func _on_fade_in_complete() -> void:
	input_active = true

func _on_fade_out_complete() -> void:
	_is_visible = false
	hide()
	input_active = false

func is_active() -> bool:
	return _is_visible and input_active

func _refresh_grid() -> void:
	for child in grid.get_children():
		child.queue_free()

	for item_id in InventoryManager.inventory:
		var def = InventoryManager.get_item_definition(item_id)
		if not def:
			def = ItemDefinition.new()
			def.id = item_id
			def.name = item_id

		var slot_scene = load("res://inventory/inventory_overlay/InventorySlot.tscn")
		var slot: InventorySlot = slot_scene.instantiate()
		grid.add_child(slot)
		slot.set_item(def)
		slot.clicked.connect(_on_slot_clicked)
		slot.right_clicked.connect(_on_slot_right_clicked)
		slot.hovered.connect(_on_slot_hovered)
		slot.unhovered.connect(_on_slot_unhovered)

	grid.columns = SLOTS_PER_ROW

func _on_slot_clicked(item_id: String) -> void:
	if not input_active:
		return

	for child in grid.get_children():
		if child is InventorySlot and child.item_id == item_id:
			if _selected_slot == null:
				_selected_slot = child
				_drag_start_time = Time.get_ticks_msec() / 1000.0
				_is_dragging = true
				_create_drag_preview(child)
			elif _selected_slot.item_id == item_id:
				item_confirmed.emit(item_id)
				hide_overlay()
			else:
				combine_requested.emit(_selected_slot.item_id, item_id)
				_clear_selection()
			break

func _on_slot_right_clicked(item_id: String) -> void:
	if not input_active:
		return
	inspect_requested.emit(item_id)
	hide_overlay()

func _on_slot_hovered(item_id: String) -> void:
	if not input_active:
		return
	_hovered_slot = null
	for child in grid.get_children():
		if child is InventorySlot and child.item_id == item_id:
			_hovered_slot = child
			break
	_update_hover_label()

func _on_slot_unhovered(item_id: String) -> void:
	if _hovered_slot and _hovered_slot.item_id == item_id:
		_hovered_slot = null
	_update_hover_label()

func _create_drag_preview(slot: InventorySlot) -> void:
	var preview = ColorRect.new()
	preview.color = Color(1, 0.6, 0.2, 0.7)
	preview.size = Vector2(48, 48)
	preview.position = slot.global_position - global_position
	panel.add_child(preview)
	_dragged_item = preview

func _handle_release_same_item() -> void:
	var elapsed = Time.get_ticks_msec() / 1000.0 - _drag_start_time
	if elapsed <= LONG_PRESS_THRESHOLD:
		item_confirmed.emit(_selected_slot.item_id)
		hide_overlay()
	else:
		_clear_selection()

func _clear_selection() -> void:
	_selected_slot = null
	_is_dragging = false
	if _dragged_item:
		_dragged_item.queue_free()
		_dragged_item = null
	_update_hover_label()

func _update_hover_label() -> void:
	if _selected_slot and _hovered_slot and _selected_slot.item_id != _hovered_slot.item_id:
		var def_a = InventoryManager.get_item_definition(_selected_slot.item_id)
		var def_b = InventoryManager.get_item_definition(_hovered_slot.item_id)
		var name_a = _selected_slot.item_id
		var name_b = _hovered_slot.item_id
		if def_a:
			name_a = def_a.name
		if def_b:
			name_b = def_b.name
		hover_label.text = "Use %s with %s" % [name_a, name_b]
	elif _hovered_slot:
		var def = InventoryManager.get_item_definition(_hovered_slot.item_id)
		if def:
			hover_label.text = def.name
		else:
			hover_label.text = _hovered_slot.item_id
	else:
		hover_label.text = ""

func _on_background_gui_input(event: InputEvent) -> void:
	if event is InputEventMouseButton and event.button_index == 1 and event.pressed:
		hide_overlay()
		close_requested.emit()

func _gui_input(event: InputEvent) -> void:
	print("HI")
	if not _is_visible:
		return

	if event is InputEventMouseButton:
		print("CLOSE")
		if event.button_index == 1 and event.pressed:
			
			_clear_selection()
			hide_overlay()
			close_requested.emit()
			if not _is_dragging:
				pass
		elif event.button_index == 1 and not event.pressed:
			if _is_dragging:
				if _hovered_slot == null:
					_clear_selection()
					hide_overlay()
					close_requested.emit()
				elif _hovered_slot == _selected_slot:
					_handle_release_same_item()
				else:
					combine_requested.emit(_selected_slot.item_id, _hovered_slot.item_id)
					_clear_selection()
			return

	if event is InputEventMouseMotion and _is_dragging and _dragged_item:
		_dragged_item.position = get_local_mouse_position() - Vector2(24, 24)
		var panel_rect = panel.get_global_rect()
		if not panel_rect.has_point(get_global_mouse_position()):
			_clear_selection()
			hide_overlay()
			close_requested.emit()

func _on_combination_attempted(item_a_id: String, item_b_id: String) -> void:
	pass

func _notification(what: int) -> void:
	if what == NOTIFICATION_PREDELETE:
		if _fade_tween:
			_fade_tween.kill()
			_fade_tween = null
