class_name TipPickup
extends Area2D

# Le pourboire qu'un client laisse sur sa table en s'en allant.
#
# Un convive qui a bien mange mais que la cuisine ne peut plus servir part decu,
# et aucune assiette ne porte plus ce qu'il doit: la sienne a ete ramassee bien
# avant, c'est meme ce ramassage qui l'avait decide a rester. Il pose donc son
# du sur la table, et le joueur passe le prendre.
#
# Rien ne se perd si personne ne vient tout de suite: l'argent attend, comme le
# paiement dort sur une assiette sale. Le ramassage se fait au contact plutot
# que par un geste dedie — la visite a deja demande tout le travail qu'elle
# valait, en exiger un de plus serait un geste sans decision derriere.

const RADIUS := 13.0
const COIN_COLOR := Color("ffb703")
const INK := Color("292137")

var amount := 0
var table_index := -1
var collected := false

func _ready() -> void:
	add_to_group("tip_pickup")
	monitoring = true
	body_entered.connect(_on_body_entered)
	z_index = 1
	queue_redraw()

func setup(new_amount: int, new_table_index: int, at: Vector2) -> void:
	amount = maxi(0, new_amount)
	table_index = new_table_index
	global_position = at
	queue_redraw()

func to_save_dictionary() -> Dictionary:
	return {
		"amount": amount,
		"table_index": table_index,
		"position_x": global_position.x,
		"position_y": global_position.y,
	}

func apply_save_dictionary(entry: Dictionary) -> void:
	amount = maxi(0, int(entry.get("amount", 0)))
	table_index = int(entry.get("table_index", -1))
	global_position = Vector2(float(entry.get("position_x", 0.0)), float(entry.get("position_y", 0.0)))
	queue_redraw()

func _on_body_entered(body: Node) -> void:
	if collected or not (body is Player):
		return
	collect()

# `body_entered` ne se declenche qu'a l'entree: un tas qui apparait sous les
# pieds du joueur, ou pendant qu'il est deja la, ne serait jamais ramasse. Le
# butin du donjon poll ses chevauchements pour la meme raison.
func _physics_process(_delta: float) -> void:
	if collected:
		return
	for body: Node2D in get_overlapping_bodies():
		if body is Player:
			collect()
			return

# Encaisser est idempotent: une seconde entree dans la zone, ou une restauration
# qui repasserait par la, ne paie pas deux fois.
func collect() -> void:
	if collected:
		return
	collected = true
	# Sortir du groupe tout de suite: `queue_free` n'agit qu'en fin de frame, et
	# d'ici la un parcours du groupe compterait encore cet argent comme pose sur
	# la table alors qu'il est deja en caisse.
	remove_from_group("tip_pickup")
	if amount > 0:
		GameState.add_coins(amount)
		GameState.toast_requested.emit(Loc.ui("ui.restaurant.tip_collected") % amount)
	queue_free()

# Le pont 3D eteint ce dessin et pose un volume a la place. Il reste la pour la
# 2D pure et pour les controles headless.
func should_draw_body() -> bool:
	return true

func _draw() -> void:
	if not should_draw_body():
		return
	# Trois pieces empilees, vues de dessus: on lit un petit tas, pas un jeton.
	for index: int in range(3):
		var at := Vector2(float(index - 1) * 4.0, float(index - 1) * -2.0)
		draw_circle(at, 7.0, COIN_COLOR)
		draw_arc(at, 7.0, 0.0, TAU, 18, INK, 1.4, true)
