extends Control

@export var player: NodePath
@export var world: NodePath
@export var hand_size = 3
@export var drawpile: Array = [
	preload("res://Cards/FirewallCard.tscn").instantiate(),
	# preload("res://Cards/FirewallCard.tscn").instantiate(),
	preload("res://Cards/CursorGunCard.tscn").instantiate(),
	# preload("res://Cards/CursorGunCard.tscn").instantiate(),
	# preload("res://Cards/DashCard.tscn").instantiate(),
	# preload("res://Cards/DashCard.tscn").instantiate(),
	preload("res://Cards/MineCard.tscn").instantiate(),
	# preload("res://Cards/MineCard.tscn").instantiate(),
	#preload("res://Cards/ShieldCard.tscn").instantiate(),
	#preload("res://Cards/ShieldCard.tscn").instantiate(),
	#preload("res://Cards/OverclockCard.tscn").instantiate(),
	#preload("res://Cards/OverclockCard.tscn").instantiate(),
	preload("res://Cards/KatanaCard.tscn").instantiate(),
	# preload("res://Cards/KatanaCard.tscn").instantiate(),
]

var active_card_index = 0

var discard_pile = [];

func _ready() -> void:
	drawpile.shuffle();
	for i in range(hand_size - get_held_cards().size()):
		draw_card()
	highlight_card(0)

func _process(_delta):
	if Input.is_action_pressed("play_card"):
		play_card()
	if Input.is_action_just_pressed("cycle_card_left"):
		cycle_card(-1);
	elif Input.is_action_just_pressed("cycle_card_right"):
		cycle_card(1);

func play_card():
	var slots = get_children()
	if active_card_index >= 0 and active_card_index < slots.size():
		var card = slots[active_card_index].get_node("Card")
		card.activate(get_node(world), get_node(player));
		# Auto-discard if out of ammo
		if card.get_ammo() <= 0:
			discard(false);
			var tween := create_tween()


func discard(do_ability = true):
	print_debug("Discarding card at index %s with name %s" % [active_card_index, get_cards().get(active_card_index).title])
	var cards = get_cards();
	if active_card_index >= 0 and active_card_index < cards.size():
		var card = cards[active_card_index]
		card.discard(get_node(world), get_node(player), do_ability)

		if do_ability:
			var old_scale = card.scale
			var old_global_pos = card.global_position
			var old_modulate = card.modulate
			var tween = create_tween()
			tween.set_trans(Tween.TRANS_BOUNCE)
			tween.tween_property(card, "scale", Vector2(1.15, 1.15), 0.1)
			tween.tween_property(card, "global_position", Vector2(50.0, 50.0), 0.05).as_relative()
			tween.tween_property(card, "global_position", Vector2((1600)/2, (900)/2), 0.15)
			#tween.parallel()
			#tween.tween_property(card, "modulate", Color(1, 1, 1, 0) , 0.2)
			tween.tween_callback(Callable(card.get_parent(), "remove_child").bind(card))
			tween.parallel()
			tween.tween_callback(Callable(discard_pile.append).bind(card))
			tween.parallel()
			tween.tween_callback(draw_card)
			# This is why we create new objects instead of moving them around like this!! grr
			tween.parallel()
			tween.tween_property(card, "scale", old_scale, 0)
			tween.parallel()
			tween.tween_property(card, "global_position", old_global_pos, 0)
			tween.parallel()
			tween.tween_property(card, "modulate", old_modulate, 0)
		else:
			discard_pile.append(card)
			card.get_parent().remove_child(card)
			draw_card();
		

		#active_card_index = min(active_card_index, hand.size() - 1);
		
	

func cycle_card(index_shift):
	var active_card_indices = get_held_cards().map(func(card): return card.get_parent().get_index())
	print_debug("Active card indices: %s" % [active_card_indices])
	if active_card_indices.size() > 0:
		var result_index = active_card_index + index_shift
		# Wrap around the result index within the hand size
		if result_index < 0:
			result_index += hand_size
		elif result_index >= hand_size:
			result_index -= hand_size

		if result_index in active_card_indices:
			active_card_index = result_index
		else:
			active_card_index = active_card_indices[0]
	else:
		push_warning("No active cards to cycle through!")
	print_debug("Current active card index: %s" % [active_card_index])

	highlight_card(active_card_index)

func highlight_card(n):
	var t = get_cards().size()
	for i in range(1, t):
		set_inactive((n + i) % t)
		
	var slot = get_slot(n)
	slot.set_z_index(1)
	var tween := create_tween()
	tween.tween_property(slot, "scale", Vector2(1.15, 1.15), 0.17)

func set_inactive(n):
	var slot = get_slot(n)
	slot.set_z_index(0)
	var tween := create_tween()
	tween.tween_property(slot, "scale", Vector2(1, 1), 0.2)
	
func get_slot(n):
	return get_children()[n]
	
func draw_card():
	var held_card_count = get_held_cards().size()
	if held_card_count == 0:
		shuffle_deck();
	if drawpile.size() > 0 and held_card_count < hand_size:
		for i in range(hand_size - held_card_count):
			var card = drawpile.pop_back();
			var empty_slots = get_card_container().get_children().filter(func(slot): return not slot.has_method("get_node") or slot.get_node_or_null("Card") == null)
			if empty_slots.size() > 0:
				empty_slots[0].add_child(card)
	else:
		cycle_card(-1)

# TODO: Reboot mechanics
func shuffle_deck():
	drawpile.append_array(discard_pile)
	discard_pile.clear();
	drawpile.shuffle();
	# active_card_index = 0;
	get_node(player).shield_active = true;
	highlight_card(active_card_index)

func get_cards() -> Array:
	return get_card_container().get_children().map(func(c): return c.get_node_or_null("Card"))

func get_held_cards() -> Array:
	return get_cards().filter(func(c): return c != null)

func get_card_container():
	return $"."

func get_active_card():
	return get_cards().get(active_card_index).get_node_or_null("Card")
