#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "HyperTwistTraining/HyperTwistTrainingTypes.h"

#include "HyperTwistFirstRunLaunchPlayerController.generated.h"

class AHyperTwistCoachDashboardActor;
class UHyperTwistFirstRunLaunchWidget;

UCLASS(BlueprintType, Blueprintable)
class UNREALHYPERTWIST_API AHyperTwistFirstRunLaunchPlayerController
	: public APlayerController
{
	GENERATED_BODY()

public:
	AHyperTwistFirstRunLaunchPlayerController();

	virtual void BeginPlay() override;
	virtual void SetupInputComponent() override;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	bool bShowFirstRunLaunchOnBeginPlay = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	int32 FirstRunLaunchZOrder = 100;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun|Diagnostics", meta = (ClampMin = "1"))
	int32 MaxFirstRunSurfaceValidationAttempts = 20;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun|Diagnostics", meta = (ClampMin = "0.01"))
	float FirstRunSurfaceValidationIntervalSeconds = 0.1f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun")
	TSubclassOf<UHyperTwistFirstRunLaunchWidget> FirstRunLaunchWidgetClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun|Dashboard")
	TSubclassOf<AHyperTwistCoachDashboardActor> DashboardActorClass;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun|Dashboard")
	FString DashboardDefaultUserId = TEXT("local-user");

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun|Dashboard")
	FString DashboardDefaultSessionId = TEXT("training_session_first_run");

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun|Dashboard")
	EHyperTwistTrainingDeliveryMode DashboardDefaultMode = EHyperTwistTrainingDeliveryMode::Timer;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist|FirstRun|Dashboard")
	int32 DashboardDefaultCoachMaxCases = 5;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|FirstRun")
	TObjectPtr<UHyperTwistFirstRunLaunchWidget> ActiveFirstRunLaunchWidget = nullptr;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|FirstRun|Dashboard")
	TObjectPtr<AHyperTwistCoachDashboardActor> ActiveDashboardActor = nullptr;

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|FirstRun")
	UHyperTwistFirstRunLaunchWidget* ShowFirstRunLaunchMenu();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|FirstRun")
	void RemoveFirstRunLaunchMenu();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|FirstRun")
	bool OpenFirstRunRoute(const FString& RouteId);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|FirstRun")
	void HandleFirstRunRouteRequested(const FString& RouteId);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|FirstRun")
	void ReturnFromAdvancedDashboard();

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|FirstRun|Dashboard")
	AHyperTwistCoachDashboardActor* EnsureCoachDashboard();

protected:
	void ApplyFirstRunInputMode();
	bool TryOpenCommandLineStartupRoute();
	void OpenMapRoute(const FString& MapAssetPath, const FString& GameModeClassPath);
	AHyperTwistCoachDashboardActor* FindExistingDashboardActor();
	AHyperTwistCoachDashboardActor* SpawnDashboardActor();
	void ApplyDashboardDefaults(AHyperTwistCoachDashboardActor* DashboardActor) const;
	void InitializeStartupDiagnostics();
	void AppendStartupDiagnosticsLine(
		const FString& Stage,
		const FString& Message,
		bool bTreatAsError = false
	);
	void PersistStartupDiagnostics(const FString& ResultStatus) const;
	bool TryRecoverFromFirstRunFailure(const FString& FailureReason);
	FString DescribeCurrentWorldName() const;
	void ScheduleFirstRunSurfaceValidation();
	void ValidateFirstRunSurfaceLayout();

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|FirstRun|Diagnostics")
	FString StartupDiagnosticsLogPath;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|FirstRun|Diagnostics")
	FString StartupSessionDiagnosticsLogPath;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|FirstRun|Diagnostics")
	FString RuntimeLogPath;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|FirstRun|Diagnostics")
	FString LastStartupFailureReason;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "HyperTwist|FirstRun|Diagnostics")
	bool bStartupRecoveryAttempted = false;

	TArray<FString> StartupDiagnosticsLines;
	FTimerHandle FirstRunSurfaceValidationTimerHandle;
	int32 FirstRunSurfaceValidationAttempt = 0;
};
