extends CharacterBody3D

class_name NPC

enum NPC_STATUS  { WALKING, LISTENING, HAPPY }

enum INTERACT_VALUES {GREAT = 35, GOOD = 22, MEH = 12}

var paletes: Array = [
	preload("res://models/paletes/pallete01.png"),
	preload("res://models/paletes/pallete02.png"),
	preload("res://models/paletes/pallete03.png"),
	preload("res://models/paletes/pallete04.png"),
	preload("res://models/paletes/pallete05.png"),
	preload("res://models/paletes/pallete06.png"),
	preload("res://models/paletes/pallete07.png"),
	preload("res://models/paletes/pallete08.png"),
	preload("res://models/paletes/pallete09.png"),
	preload("res://models/paletes/pallete10.png"),
	preload("res://models/paletes/pallete11.png"),
	preload("res://models/paletes/pallete12.png")
]

@onready var sad_sprite = $SadSprite
@onready var listen_sprite = $ListenSprite
@onready var happy_sprite = $HappySprite
@onready var persona = $persona
@onready var delete_timer = $DeleteTimer
@onready var navigation_agent: NavigationAgent3D = $NavigationAgent3D

var mood_scale : float
var status = NPC_STATUS.WALKING
var player
var score = 10

var movement_target: Vector3
var movement_speed: float = 0.8
var movement_delta: float

var what_is_expected: Array = [1,2,3]

func _ready():
	navigation_agent.velocity_computed.connect(Callable(on_velocity_computed))
	prepare_npc()


func _process(delta):
	if (status == NPC_STATUS.LISTENING):
		check_state()


func _physics_process(delta):
	if navigation_agent.is_navigation_finished():
		if (delete_timer.is_stopped()):
			delete_timer.start()
		return

	if (status != NPC_STATUS.WALKING):
		return

	var next_path_position: Vector3 = navigation_agent.get_next_path_position()
	var new_velocity: Vector3 = global_position.direction_to(next_path_position) * movement_speed
	if navigation_agent.avoidance_enabled:
		navigation_agent.set_velocity(new_velocity)
	else:
		on_velocity_computed(new_velocity)


func prepare_npc():
	%ExpectLabel.visible = false
	listen_sprite.visible = false
	happy_sprite.visible = false
	
	var mat = StandardMaterial3D.new()
	var m = paletes[randi_range(0, paletes.size() - 1)]
	mat.albedo_texture = m
	persona.get_node("PersonA/Skeleton3D/Person").set_surface_override_material(0, mat)
	score = randi_range(5, 15)
	mood_scale = score * 0.5

	persona.get_node("AnimationPlayer").play("SadWalk")

func set_destination(destination : Vector3):
	navigation_agent.set_target_position(destination)
	var des = destination.normalized()
	persona.look_at(position - des, Vector3.UP)


func check_state():
	if (mood_scale <= 0):
		status = NPC_STATUS.HAPPY
		happy_sprite.visible = true
		listen_sprite.visible = false
		sad_sprite.visible = false
		player.npc_made_happy(score)
		persona.get_node("AnimationPlayer").play("HappyJumps")
		delete_timer.start()
		player = null
		AudioPlayer.play_npc_happy()


func talk_to(player_to_talk_to):
	player = player_to_talk_to
	status = NPC_STATUS.LISTENING
	listen_sprite.visible = true
	sad_sprite.visible = false
	happy_sprite.visible = false
	#persona.look_at(player_to_talk_to.global_position, Vector3.UP)
	get_next_expected()

func on_velocity_computed(safe_velocity: Vector3):
	velocity = safe_velocity
	move_and_slide()
	
func get_next_expected():
	what_is_expected.shuffle()


func player_did_something(what_he_did : int):
	if (what_he_did == what_is_expected[0]):
		mood_scale -= (INTERACT_VALUES.GREAT / 10)
		update_expect_label("PLAYER_DID_GREAT", Color(0.2, 1.0, 0.0, 1.0))
	elif (what_he_did == what_is_expected[1]):
		mood_scale -= (INTERACT_VALUES.GOOD / 10)
		update_expect_label("PLAYER_DID_GOOD", Color(0.5, 0.8, 0.0, 1.0))
	else:
		mood_scale -= (INTERACT_VALUES.MEH / 10)
		update_expect_label("PLAYER_DID_MEH", Color(0.8, 0.8, 0.1, 1.0))

	get_next_expected()

	await get_tree().create_timer(1.2).timeout
	%ExpectLabel.visible = false
	
func update_expect_label(m : String, c : Color):
	%ExpectLabel.modulate = c
	%ExpectLabel.text = tr(m)
	%ExpectLabel.visible = true

func _on_delete_timer_timeout():
	if (status != NPC_STATUS.LISTENING):
		queue_free()
