#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "HyperTwistRecognition/HyperTwistRecognitionReplayLibrary.h"
#include "HyperTwistReplay/HyperTwistReplayReviewLibrary.h"
#include "HyperTwistTraining/HyperTwistTrainingTypes.h"
#include "HyperTwistTrainingAnalyticsLibrary.generated.h"

UENUM(BlueprintType)
enum class EHyperTwistTrainingAnalyticsMetricKind : uint8
{
	Count UMETA(DisplayName = "Count"),
	DurationMs UMETA(DisplayName = "Duration (ms)"),
	Percentage UMETA(DisplayName = "Percentage"),
	Ratio UMETA(DisplayName = "Ratio"),
	Score UMETA(DisplayName = "Score")
};

UENUM(BlueprintType)
enum class EHyperTwistTrainingAnalyticsVisualizationKind : uint8
{
	StatGrid UMETA(DisplayName = "Stat Grid"),
	BarChart UMETA(DisplayName = "Bar Chart"),
	LineChart UMETA(DisplayName = "Line Chart"),
	ComparisonTable UMETA(DisplayName = "Comparison Table"),
	RollingWindowTrend UMETA(DisplayName = "Rolling Window Trend"),
	SplitLadder UMETA(DisplayName = "Split Ladder")
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingAnalyticsDataPoint
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString PointId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Label;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString SecondaryLabel;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	float NumericValue = 0.0f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	EHyperTwistTrainingAnalyticsMetricKind MetricKind = EHyperTwistTrainingAnalyticsMetricKind::Count;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bHighlighted = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> Tags;

	bool IsStructurallyValid() const
	{
		return !PointId.IsEmpty() && !Label.IsEmpty();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingAnalyticsSeries
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString SeriesId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Label;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Summary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	EHyperTwistTrainingAnalyticsMetricKind MetricKind = EHyperTwistTrainingAnalyticsMetricKind::Count;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingAnalyticsDataPoint> DataPoints;

	bool IsStructurallyValid() const
	{
		return !SeriesId.IsEmpty() && !Label.IsEmpty() && DataPoints.Num() > 0;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingAnalyticsExportSurface
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString FileStem;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> ColumnOrder;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> AccessibilitySummaryLines;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> RecommendedInteractions;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> OptionalSidecars;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bSupportsTabularDataView = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bSupportsImageExport = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	bool bSupportsServerRenderedView = true;

	bool IsStructurallyValid() const
	{
		return !FileStem.IsEmpty() && ColumnOrder.Num() > 0;
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingAnalyticsReportDefinition
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString ReportId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Title;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString Summary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	EHyperTwistTrainingAnalyticsVisualizationKind VisualizationKind =
		EHyperTwistTrainingAnalyticsVisualizationKind::StatGrid;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingAnalyticsSeries> Series;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FString> InsightLines;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingAnalyticsExportSurface ExportSurface;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingSourceAttribution SourceAttribution;

	bool IsStructurallyValid() const
	{
		return !ReportId.IsEmpty()
			&& !Title.IsEmpty()
			&& ExportSurface.IsStructurallyValid()
			&& SourceAttribution.IsStructurallyValid();
	}
};

USTRUCT(BlueprintType)
struct FHyperTwistTrainingAnalyticsReportBundle
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString UserId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString DeckId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString CaseId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString ReferenceUtc;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FString PrimaryReportId;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingSessionSummary SessionSummary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingDeckHistorySummary DeckHistorySummary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingTimingTrendSummary TimingTrendSummary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingPersonalBestSummary PersonalBestSummary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingDeckScopedStats DeckScopedStats;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingCaseScopedStats CaseScopedStats;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistTrainingLiveTimerState LiveTimerState;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistReplayReviewAnalytics ReplayReviewAnalytics;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	FHyperTwistRecognitionReplaySummary RecognitionReplaySummary;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "HyperTwist")
	TArray<FHyperTwistTrainingAnalyticsReportDefinition> Reports;

	bool IsStructurallyValid() const
	{
		return !DeckId.IsEmpty() && Reports.Num() > 0;
	}
};

UCLASS()
class UNREALHYPERTWIST_API UHyperTwistTrainingAnalyticsLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Analytics")
	static FHyperTwistTrainingSessionDomainBundle BuildSessionDomainBundle(
		const FHyperTwistTrainingSession& Session,
		const FHyperTwistTrainingSessionSummary& TrainingSession,
		const FHyperTwistTrainingAttempt& SolveAttempt,
		const FHyperTwistTrainingTemplateLaunchProvenance& TemplateLaunchProvenance,
		const FHyperTwistTrainingCoachPanelState& CoachPanelState,
		const FHyperTwistTrainingMethodDrillRunState& MethodDrillRunState,
		const FHyperTwistTrainingAnalyticsReportBundle& ReportBundle
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Analytics")
	static FHyperTwistTrainingAnalyticsReportBundle BuildActiveTrainingAnalyticsReportBundle(
		const FHyperTwistTrainingSessionSummary& SessionSummary,
		const FHyperTwistTrainingDeckHistorySummary& DeckHistorySummary,
		const FHyperTwistTrainingTimingTrendSummary& TimingTrendSummary,
		const FHyperTwistTrainingPersonalBestSummary& PersonalBestSummary,
		const FHyperTwistTrainingDeckScopedStats& DeckScopedStats,
		const FHyperTwistTrainingCaseScopedStats& CaseScopedStats,
		const FHyperTwistTrainingLiveTimerState& LiveTimerState,
		const FHyperTwistReplayReviewAnalytics& ReplayReviewAnalytics,
		const FHyperTwistRecognitionReplaySummary& RecognitionReplaySummary
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Analytics")
	static FHyperTwistTrainingAnalyticsPanelContractBundle BuildAnalyticsPanelContractBundle(
		const FHyperTwistTrainingSessionDomainBundle& SessionDomainBundle,
		const FHyperTwistTrainingAnalyticsReportBundle& ReportBundle
	);

	UFUNCTION(BlueprintCallable, Category = "HyperTwist|Training|Analytics")
	static bool TryGetReportById(
		const FHyperTwistTrainingAnalyticsReportBundle& Bundle,
		const FString& ReportId,
		FHyperTwistTrainingAnalyticsReportDefinition& OutReport
	);

	UFUNCTION(BlueprintPure, Category = "HyperTwist|Training|Analytics")
	static FString BuildReportDataViewTsv(const FHyperTwistTrainingAnalyticsReportDefinition& Report);
};
