class_name BossFightCutscenes
extends CanvasLayer

@export var camera_move_speed : float = 20
@export var behind_door_position : Node2D
@export var before_boss_position : Node2D
@export var boss : Boss
@export var dialogues : Array[Dialogue]
var dialogue_id : int = 0
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@export var cutscene_animation_player : AnimationPlayer

var finished_animation = false

@onready var dialogue_box: DialogueBox = $DialogueBox
@onready var color_rect: ColorRect = $ColorRect

@onready var player : Player = $"../../../Player"
@onready var player_cam : CameraController = $"../../../CameraController"
var target_position : Vector2
enum INTRO_ANIMATION_WALK_SECTION {BEHIND_DOOR, TO_BOSS}
var walk_stage : INTRO_ANIMATION_WALK_SECTION = INTRO_ANIMATION_WALK_SECTION.BEHIND_DOOR

var moving_camera : bool = false

func _ready() -> void:
	force_time_shift()

func force_time_shift():
	var maploader = get_parent().get_parent() as MapLoader
	if player == null:
		return
	if Globals.current_time == Utils.TIME.PRESENT:
		return
	
	Globals.current_time = Utils.TIME.PRESENT
	player.global_position.y -= maploader.get_timeshift_offset(Globals.current_time)
	SignalBus.changed_player_position.emit()

func intro_cutscene():
	SignalBus.entered_boss_room.emit()  # for music
	dialogue_id = 0
	if Globals.skip_cutscenes:
		if not player:
			player = $"../../../Player" as Player
		var parent_room = get_parent() as MapRoom
		if not parent_room.is_player_positioning_handled:
			await parent_room.handled_player_positioning
		player.global_position = before_boss_position.global_position
		if color_rect:
			color_rect.color = Color(0, 0, 0, 0)
		if cutscene_animation_player:
			cutscene_animation_player.play("skip")
		continue_after_cutscene()
	else:
		_cutscene_start()
		if is_inside_tree():
			await get_tree().create_timer(0.5).timeout  
		animation_player.play("slow_fade_in")
		if cutscene_animation_player:
			cutscene_animation_player.play("intro_animation")

func mid_cutscene():
	dialogue_id = 1
	if Globals.skip_cutscenes:
		continue_after_cutscene()
	else:
		_cutscene_start()
		start_dialogue()

func end_cutscene():
	dialogue_id = 2
	if Globals.skip_cutscenes:
		continue_after_cutscene()
	else:
		_cutscene_start()
		start_dialogue()

func start_dialogue(_x = null):
	dialogue_box.dialogues = dialogues[dialogue_id].dialogue.duplicate()
	dialogue_box.start()

func _on_dialogue_box_dialogue_finished() -> void:
	_cutscene_end()
	continue_after_cutscene()

func continue_after_cutscene():
	if boss:
		match dialogue_id:
			0:
				PlayerVariables.reset_health()
				boss.start_bossfight()
			1:
				SceneChanger.mid_animation = false
				SignalBus.emit_boss_reload_anchor()
			2:
				SceneChanger.mid_animation = false
				boss.die()

func _cutscene_start():
	show()
	boss.boss_behavior.hide_ui()
	GUI.in_game_gui.hide()
	Globals.pause()
	SceneChanger.mid_animation = true

func _cutscene_end():
	camera_rebound()
	boss.boss_behavior.enemy_health.show()
	Globals.unpause()
	GUI.in_game_gui.show()
	hide()

func _physics_process(_delta: float) -> void:
	if not Globals.forcing_player_movement:
		return
	player.player_base.animation_walk(Vector2.UP)
	if player.player_base.global_position.y < target_position.y:
		if walk_stage == INTRO_ANIMATION_WALK_SECTION.BEHIND_DOOR:
			cutscene_animation_player.play("door_slam")
			Globals.forcing_player_movement = false
			walk_stage = INTRO_ANIMATION_WALK_SECTION.TO_BOSS
		elif INTRO_ANIMATION_WALK_SECTION.TO_BOSS:
			Globals.forcing_player_movement = false
			force_camera_up()

func _process(delta: float) -> void:
	if not moving_camera:
		return
	player_cam.offset.y -= camera_move_speed * delta

func player_walk_forward():
	if not player:
		player = $"../../../Player" as Player
	if walk_stage == INTRO_ANIMATION_WALK_SECTION.BEHIND_DOOR:
		target_position = behind_door_position.global_position
	elif walk_stage == INTRO_ANIMATION_WALK_SECTION.TO_BOSS:
		target_position = before_boss_position.global_position
	Globals.forcing_player_movement = true

func force_camera_up():
	if not player_cam:
		player_cam = $"../../../CameraController" as CameraController
	moving_camera = true

func camera_rebound():
	if not player_cam:
		player_cam = $"../../../CameraController" as CameraController
	player_cam.offset = Vector2.ZERO
	moving_camera = false


func _on_visible_on_screen_notifier_2d_screen_entered() -> void:
	moving_camera = false
	start_dialogue()
