class_name ItemSpawner extends Marker3D
## Entity that spawns a given item when conditions are met.

signal item_spawned(item: Item)

const POP_IN_TIME := 1.618

## Item to be spawned
@export var item: PackedScene

## Quantity of the given item to include in the spawned item pickup, where applicable.
@export var amount: int = 1

@export_category("Spawn Conditions")
## Spawn an item when the tree is loaded.
@export var spawn_on_ready: bool = false

## After spawning one item, don't spawn any more.
@export var one_shot: bool = false

## Spawn an item after this many turns.
## 1 indicates the item should be spawned on the next turn.
## 0 indicates the item should not be spawned based on turns.
@export var spawn_turns: int = 0

## Spawn an item after this many seconds.
## Make sure this is long enough that a player won't just keep picking it up!
## Values < 0 indicate the item should not be spawned based on time.
@export var spawn_time: float = -1

var turns_to_spawn := -1


func _ready() -> void:
	var world: World = get_tree().get_first_node_in_group(World.group)
	if world:
		world.manager.turn_started.connect(_on_turn_started)

	if spawn_on_ready:
		spawn()
	else:
		_set_spawn_conditions()


## Spawn the item!
## This can be called manually if an item needs complex spawning logic.
func spawn() -> void:
	var instance: Item = item.instantiate()
	instance.amount = amount
	instance.on_collect.connect(_on_item_collected)
	add_child(instance)

	# Pop-in animation
	instance.scale = Vector3.ONE * 1e-6
	var tween := create_tween()
	tween.tween_property(instance, "scale", Vector3.ONE, POP_IN_TIME).set_trans(Tween.TRANS_SPRING)

	item_spawned.emit(instance)


func _set_spawn_conditions() -> void:
	if spawn_time >= 0:
		get_tree().create_timer(spawn_time).timeout.connect(spawn)

	if spawn_turns > 0:
		turns_to_spawn = spawn_turns


func _on_item_collected(_player: WorldPlayer) -> void:
	if not one_shot:
		_set_spawn_conditions()


func _on_turn_started(_player: WorldPlayer) -> void:
	turns_to_spawn -= 1
	if turns_to_spawn == 0:
		spawn()
