class_name InteractiveProp
extends Node2D

@export_enum("dungeon", "restaurant", "cooking", "upgrades", "dishwasher", "trash", "shelf", "next_room", "console", "takeout") var action := "dungeon"
@export var prompt := "Interact"
@export var label := "Station"
@export var color := Color("ffbe0b")
@export var size := Vector2(72, 72)
@export var solid := true

var body: StaticBody2D
# Rang du poste quand la scène en compte plusieurs du même genre. -1 signifie
# « poste unique »: le niveau est alors interrogé comme avant, ce qui laisse le
# donjon et ses accessoires intacts.
var station_index := -1

func _ready() -> void:
	add_to_group("interactable")
	if ["dishwasher", "trash", "shelf"].has(action):
		add_to_group("dish_receiver")
	if solid:
		_build_collision()
	set_process(true)
	queue_redraw()

var _had_status := false

func _process(_delta: float) -> void:
	# Stations render live status (cooking progress, stored plates), so they have
	# to repaint while the level state changes rather than only on setup.
	var has_status := not _status().is_empty()
	# Repaint once more on the frame the status disappears, otherwise the last
	# cooking caption would stay burned in and never return to the label.
	if not has_status and not _had_status:
		return
	_had_status = has_status
	queue_redraw()

func _build_collision() -> void:
	body = StaticBody2D.new()
	body.name = "PropBody"
	# Layer 2 is the "world blocker" layer the player already collides with.
	body.collision_layer = 2
	body.collision_mask = 0
	var collision := CollisionShape2D.new()
	var shape := RectangleShape2D.new()
	shape.size = size
	collision.shape = shape
	body.add_child(collision)
	add_child(body)

# Un poste peut être retaillé après son démarrage: l'étagère prend la hauteur de
# la colonne des fours, qui n'est connue qu'une fois les postes placés. La
# collision suit le dessin, sinon le corps mentirait sur ce qu'on voit.
func resize(new_size: Vector2) -> void:
	size = new_size
	if body != null and is_instance_valid(body):
		for child: Node in body.get_children():
			if child is CollisionShape2D and (child as CollisionShape2D).shape is RectangleShape2D:
				((child as CollisionShape2D).shape as RectangleShape2D).size = new_size
	queue_redraw()

func interact(_player: Player) -> void:
	var level := get_tree().get_first_node_in_group("level")
	if level == null:
		return
	if station_index >= 0 and level.has_method("handle_station_interaction"):
		level.handle_station_interaction(action, station_index)
		return
	if level.has_method("handle_interaction"):
		level.handle_interaction(action)

func get_prompt() -> String:
	var level := get_tree().get_first_node_in_group("level")
	if level == null:
		return prompt
	if station_index >= 0 and level.has_method("get_station_prompt"):
		return level.get_station_prompt(action, station_index, prompt)
	if level.has_method("get_interaction_prompt"):
		return level.get_interaction_prompt(action, prompt)
	return prompt

func _status() -> Dictionary:
	var level := get_tree().get_first_node_in_group("level")
	if level == null:
		return {}
	if station_index >= 0 and level.has_method("get_indexed_station_status"):
		return level.get_indexed_station_status(action, station_index)
	if level.has_method("get_station_status"):
		return level.get_station_status(action)
	return {}

func _draw() -> void:
	var rect := Rect2(-size * 0.5, size)
	draw_rect(rect, color)
	draw_rect(rect, color.lightened(0.35), false, 4.0)
	var status := _status()
	if status.is_empty():
		draw_string(ThemeDB.fallback_font, Vector2(-size.x * 0.42, 5), label, HORIZONTAL_ALIGNMENT_CENTER, size.x * 0.84, 16, Color("20152c"))
		return
	# A station with live status replaces its static label with that status, so
	# the player reads production from the appliance instead of a global caption.
	var lines: Array = status.get("lines", [])
	var line_height := 13.0
	var block_top := -float(lines.size()) * line_height * 0.5
	for index: int in range(lines.size()):
		draw_string(ThemeDB.fallback_font, Vector2(-size.x * 0.46, block_top + line_height * (float(index) + 0.78)), str(lines[index]), HORIZONTAL_ALIGNMENT_CENTER, size.x * 0.92, 12, Color("20152c"))
	if status.has("progress"):
		var bar := Rect2(-size.x * 0.40, size.y * 0.5 - 13.0, size.x * 0.80, 7.0)
		draw_rect(bar, Color(0.11, 0.08, 0.16, 0.85))
		var filled := bar
		filled.size.x = bar.size.x * clampf(float(status.progress), 0.0, 1.0)
		draw_rect(filled, Color("4ade80"))
		draw_rect(bar, Color("20152c"), false, 2.0)
