extends Node

@onready var bubbles: HBoxContainer = %Bubbles
@onready var bubbles_back: TileMapLayer = %BubblesBack
@onready var bubbles_interior: TileMapLayer = %BubblesInterior

@onready var bubble_label: RichTextLabel = %BubbleLabel
@onready var left_speaker: TextureRect = %LeftSpeaker
@onready var right_speaker: TextureRect = %RightSpeaker

@onready var time_between_letters: Timer = $TimeBetweenLetters
@onready var ui_flicker_timer: Timer = $UIFlickerTimer
@onready var e_ui_button: TextureRect = %E
@onready var next_label: Label = %NextLabel

@export_multiline var dialogue = ""
@export var start_with_left = false
@export var left_picture: Texture2D
@export var right_picture: Texture2D
@onready var dialogue_player: AudioStreamPlayer = $DialoguePlayer

signal dialogue_ended

var dialogue_steps = []
var current_dialogue = ""
var current_dialogue_split: PackedStringArray = []
var is_dialogue_ongoing = false
var is_left_speaking = false

func _ready() -> void:
	is_left_speaking = start_with_left
	
	e_ui_button.visible = false
	next_label.visible = false
	
	var steps = dialogue.split("---")
	for step: String in steps:
		dialogue_steps.append(step.strip_edges())
		
func display_profiles():
	left_speaker.texture = left_picture
	right_speaker.texture = right_picture
	
	left_speaker.visible = is_left_speaking
	right_speaker.visible = not is_left_speaking

func toggle_ui():
	e_ui_button.visible = not e_ui_button.visible

func _process(delta: float) -> void:
	if not is_dialogue_ongoing:
		return
	
	if Input.is_action_just_pressed("interact"):
		if not current_dialogue_split.is_empty():
			return
		if dialogue_steps.is_empty():
			end_dialogue()
			return
		else:
			# toggle speakers
			is_left_speaking = not is_left_speaking
			display_profiles()
			load_next_dialogue()

func load_next_dialogue():
	var next_dialogue = dialogue_steps.pop_front()
	current_dialogue = ""
	current_dialogue_split = next_dialogue.split("")
	
func on_dialogue_started():
	bubbles.visible = true
	bubble_label.visible = true
	bubbles_back.visible = true
	bubbles_interior.visible = true
	display_profiles()
	is_dialogue_ongoing = true
	time_between_letters.start()
	load_next_dialogue()
	
func end_dialogue():
	bubbles.visible = false
	bubble_label.visible = false
	bubbles_back.visible = false
	bubbles_interior.visible = false
	e_ui_button.visible = false
	next_label.visible = false
	
	is_dialogue_ongoing = false
	time_between_letters.stop()
	ui_flicker_timer.stop()
	
	dialogue_ended.emit()

func _on_next_letter() -> void:
	if not current_dialogue_split.is_empty():
		ui_flicker_timer.stop()
		e_ui_button.visible = false
		next_label.visible = false
		dialogue_player.pitch_scale = randf_range(5, 6)
		dialogue_player.play()
		var next_letter = current_dialogue_split.get(0)
		current_dialogue_split.remove_at(0)
		current_dialogue += next_letter
		bubble_label.text = current_dialogue
	else:
		if next_label.visible:
			return
			
		next_label.visible = true
		ui_flicker_timer.start()


func _on_body_entered_trigger_dialogue(body: Node2D) -> void:
	on_dialogue_started()
