extends Node3D

@onready var track_generator: TrackGenerator = $TrackGenerator
@onready var train: Train = $Train
@onready var camera: TrainJourneyCamera = $TrainCamera

@onready var speed_label : Label = $HUD/speed_label
@onready var camera_label : Label = $HUD/camera_label
@onready var distance_label : Label = $HUD/tripdistance_label
@onready var total_distance_label : Label = $HUD/totaldistance_label
@onready var time_label : Label = $HUD/triptime_label
@onready var totaltime_label : Label = $HUD/totaltime_label
@onready var auto_save_timer = $AutoSaveTimer
@onready var trip_timer = $TripTime

var savegame_path: String = "user://savegame.save"
var total_time_in_secs : int = 0
@export var main_scene: PackedScene


func _ready() -> void:
	# caricamento stato gioco
	load_game()

	# avvia autosaver
	auto_save_timer.start()
	# time
	trip_timer.start()

	train.track_generator = track_generator
	camera.train = train
	
	# Terreno
	var ground = MeshInstance3D.new()
	ground.name = "Ground"
	var plane = PlaneMesh.new()
	plane.size = Vector2(2000, 2000)
	ground.mesh = plane
	
	var ground_mat = StandardMaterial3D.new()
	ground_mat.albedo_color = Color(0.35, 0.48, 0.28)
	ground_mat.roughness = 1.0
	ground.material_override = ground_mat
	ground.position.y = -0.15
	add_child(ground)


func _process(_delta: float) -> void:
	_update_ui()
	_update_ground()
	
	if Input.is_action_just_pressed("ui_cancel"):
		SceneSwitcher.switch_scene(main_scene.resource_path)


func _update_ui() -> void:
	if speed_label and train:
		var kmh = train.get_speed() * 3.6
		speed_label.text = "Velocità: %.0f km/h" % kmh
	
	if distance_label and train:
		var km = train.distance_traveled / 1000.0
		distance_label.text = "Distanza viaggio: %.2f km" % km

	if total_distance_label and train:
		Gamestate.total_distance = train.distance_traveled
		var km = (Gamestate.total_distance + Gamestate.initial_distance) / 1000
		total_distance_label.text = "Distanza totale: %.2f km" % km

	if time_label and train:
		var h = int(total_time_in_secs / 3600.0)
		var m = int(total_time_in_secs / 60.0)
		var s = total_time_in_secs - m * 60		
		time_label.text = "Tempo viaggio: %02d:%02d:%02d" % [h, m, s]
	
	if totaltime_label and train:
		Gamestate.total_time = total_time_in_secs
		var tot = Gamestate.total_time + Gamestate.initial_time
		var h = int(tot / 3600.0)
		var m = int(tot / 60.0)
		var s = tot - m * 60		
		totaltime_label.text = "Tempo totale: %02d:%02d:%02d" % [h, m, s]
		
	if camera_label and camera:
		camera_label.text = "Camera: %s" % camera.get_mode_name()


func _update_ground() -> void:
	var ground = get_node_or_null("Ground")
	if ground and train:
		var pos = train.get_locomotive_position()
		ground.position.x = pos.x
		ground.position.z = pos.z


func save_game():
	var save_file = FileAccess.open(savegame_path, FileAccess.WRITE)
	var save_nodes = get_tree().get_nodes_in_group("save_data")
	
	for node in save_nodes:
		if !node.has_method("save"):
			continue
		var node_data = node.call("save")  # ogni nodo implementa il suo save()
		save_file.store_line(JSON.stringify(node_data))


func load_game():
	if not FileAccess.file_exists(savegame_path):
		return  # nessun salvataggio trovato

	var save_file = FileAccess.open(savegame_path, FileAccess.READ)
	while save_file.get_position() < save_file.get_length():
		var json_string = save_file.get_line()
		var node_data = JSON.parse_string(json_string)
		
		if node_data == null:
			continue
		
		if node_data["filename"] == "res://scenes/gamestate.tscn" and node_data["parent"] == "/root":
			Gamestate.SetInitialValue(node_data["total_distance"], node_data["total_time"])


func _on_timer_timeout() -> void:
	save_game()


func _on_trip_time_timeout() -> void:
	total_time_in_secs += 1
	
