extends Node3D

const FAILED_DIALOG = "res://dialogs/timelines/X_gameplay_related/demeter_ship_failed.dtl"

const TAKE_OFF_ICON = preload("res://common/icons/chevrons-up.svg")
const LAND_ICON = preload("res://common/icons/arrow-narrow-down.svg")
const RUN_POINT_ICON = preload("res://common/icons/map-pin.svg")

signal take_off
signal land

@onready var dashboard : Dashboard = %Dashboard
var choosen_run_point : RunPoint = null
var exiting = false
var phone_dialogs : Array[String]
var respawn_asked = false

# Called when the node enters the scene tree for the first time.
func _ready():
    var region_data = GameInfo.game_data.current_region_data
    
    %Gauge3D.progress = (
        1. if (region_data == null or region_data.state == RegionData.State.SUCCEEDED) 
        else (float(region_data.get_score()) / max(float(region_data.objective), 1))
    )

    update_dashboard(false)

    dashboard.main_screen_activated.connect(_on_main_screen_activated)
    dashboard.left_screen_activated.connect(_on_left_screen_activated)
    dashboard.right_screen_activated.connect(_on_right_screen_activated)
    %Exit.clicked.connect(_on_exit_clicked)
    %Exit.interactable = can_exit()
    
    if not "ship" in GameInfo.game_data.tutorials_done:
        await get_tree().create_timer(1).timeout
        %ShipTutorial.appear()
    
    dashboard.destination_text = GameInfo.game_data.current_run.story_step.get_destination_text()

    %Phone.visible = GameInfo.game_data.game_mode == GameData.Mode.STORY
    %InfiniteModeScreen.visible = GameInfo.game_data.game_mode == GameData.Mode.INFINITE
    %Pearl.visible = GameInfo.game_data.current_run.story_step is AstraStoryStep

    update_dialogs()

func update_dialogs():
    if GameInfo.game_data and GameInfo.game_data.current_run:
        var run_data = GameInfo.game_data.current_run
        var region_data = GameInfo.game_data.current_region_data

        if (
            region_data
            and region_data.state != RegionData.State.SUCCEEDED
            and region_data.charges == 0
            and not FAILED_DIALOG in GameInfo.game_data.dialogs_done
            and not FAILED_DIALOG in phone_dialogs
            and not GameInfo.game_data.current_run.story_step is InfiniteStoryStep
        ):
            phone_dialogs.append(FAILED_DIALOG)

        var story_dialog = run_data.story_step.get_ship_dialog_path(run_data.level, run_data.difficulty_setting, GameInfo.game_data.ship_in_space)
        if (
            story_dialog
            and not story_dialog in GameInfo.game_data.dialogs_done
            and not story_dialog in phone_dialogs
        ):
            phone_dialogs.append(story_dialog)
        

        if len(phone_dialogs) and Dialogic.current_timeline == null:
            await get_tree().create_timer(randf_range(0.5,3.)).timeout
            ring_phone()


func ring_phone():
    %Phone.interactable = true
    %Phone.play_audio()

func _on_phone_clicked():
    %Phone.stop_audio()
    %Phone.interactable = false
    if len(phone_dialogs):
        var phone_dialog :  String = phone_dialogs.pop_front()
        Dialogic.start(phone_dialog)
        await Dialogic.timeline_ended
        if phone_dialog == FAILED_DIALOG:
            %FailTutorial.appear()
        if (len(phone_dialogs)):
            await get_tree().create_timer(randf_range(0.2,1.)).timeout
            ring_phone()
        

func move_to_choosen_run_point():
    GameInfo.game_data.current_run.choose_next_run_point(choosen_run_point)
    %InfiniteModeScreen.fetch_game_values()

func can_exit() -> bool:
    return (
        not GameInfo.game_data.ship_in_space 
        and GameInfo.game_data.current_region_data != null 
        and not GameInfo.game_data.current_run.story_step is TutorialStoryStep
    )

func _on_main_screen_activated():
    if GameInfo.game_data.ship_in_space:
        if GameInfo.game_data.current_run and choosen_run_point:
            move_to_choosen_run_point()
        land.emit()
        GameInfo.game_data.ship_in_space = false
        %PlantInfoScreen.update_plant_info()
        update_dialogs()

    else :
        take_off.emit()
        GameInfo.game_data.ship_in_space = true
        if GameInfo.game_data.current_run == null:
            GameInfo.game_data.start_run()
        GameInfo.game_data.progression_data.update_best_run(GameInfo.game_data.current_run)
        GameInfo.game_data.player_data.energy = GameInfo.game_data.player_data.max_energy
    
        var gauge_tween = get_tree().create_tween()
        gauge_tween.tween_property(%Gauge3D,"progress",0,3.)
        update_dialogs()
    %Exit.interactable = can_exit()
    update_dashboard()

func _on_left_screen_activated():
    AudioManager.play_sfx("Screen_interaction")
    if GameInfo.game_data.current_run and len(GameInfo.game_data.current_run.next_run_points) > 0:
        choosen_run_point = GameInfo.game_data.current_run.next_run_points[0]
        update_dashboard()

func _on_right_screen_activated():
    AudioManager.play_sfx("Screen_interaction")
    if GameInfo.game_data.current_run and len(GameInfo.game_data.current_run.next_run_points) > 1:
        choosen_run_point = GameInfo.game_data.current_run.next_run_points[1]
        update_dashboard()

func _on_exit_clicked():
    if (can_exit() and not exiting):
        AudioManager.play_sfx("Ship_exit")
        exiting = true
        if GameInfo.game_data.current_run:
            SceneManager.change_to_scene(GameInfo.game_data.current_run.get_cockpit_exit_scene())

func update_dashboard(with_animation := true):

    var current_region_data = GameInfo.game_data.current_region_data
    var current_run = GameInfo.game_data.current_run

    dashboard.run_data = current_run
    dashboard.in_space = GameInfo.game_data.ship_in_space
    dashboard.update_travel_screen(with_animation, not with_animation)

    var can_take_off : bool = (
        not current_run.is_finished()
        and current_region_data
        and current_region_data.state == RegionData.State.SUCCEEDED
        and current_run
        and len(current_run.next_run_points) != 0
        or GameInfo.game_data.current_region_data == null
    )

    if GameInfo.game_data.ship_in_space:
        if choosen_run_point:
            dashboard.main_screen_run_point = choosen_run_point
            dashboard.main_screen_state = DashboardMainScreen.State.READY_TO_LAND
            dashboard.status_text = ""
        else:
            dashboard.main_screen_state = DashboardMainScreen.State.WAITING_CHOICE
            dashboard.status_text = tr("CHOOSE_NEXT_STOP")

        if GameInfo.game_data.current_run:
            var next_run_points = GameInfo.game_data.current_run.next_run_points
            if len(next_run_points) > 0:
                dashboard.left_stop = next_run_points[0]
            else:
                dashboard.left_stop = null
                
            if len(next_run_points) > 1:
                dashboard.right_stop = next_run_points[1]
            else:
                dashboard.right_stop = null
    else :
        if can_take_off:
            dashboard.main_screen_state = DashboardMainScreen.State.READY_TO_TAKE_OFF
        else:
            dashboard.main_screen_run_point = current_run.current_run_point
            dashboard.main_screen_state = DashboardMainScreen.State.LANDED
            dashboard.status_text = "DESTINATION_REACHED" if current_run.is_finished() else tr("NO_MORE_ENERGY")


        dashboard.left_stop = null
        dashboard.right_stop = null

func _on_orchid_saver_clicked():
    if not respawn_asked:
        respawn_asked = true
        %OrchidSaver.screen_icon = preload("res://common/icons/alert-triangle.svg")
        %OrchidSaver.screen_text = tr("CONFIRM_RESPAWN")
    else:
        GameInfo.game_data.give_up()
