// Copyright Epic Games, Inc. All Rights Reserved.
// UE5 Modular Game Framework — GM_CoreGameMode (05)
// Core Game Mode. Server-authoritative session rules, player spawning, chapter
// transitions, death routing. In C++, extends the replicated GameMode base for
// full networking support.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "GameplayTagContainer.h"
#include "GM_CoreGameMode.generated.h"

// Forward declarations
class UGI_GameFramework;
class AGS_CoreGameState;

// Delegates
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnChapterTransition, FGameplayTag, NewChapter);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGameOverTriggered, FGameplayTag, EndingTag);

/**
 * GM_CoreGameMode — Core Game Mode.
 *
 * Sets the rules of the game session: which pawn, controller, player state,
 * HUD, and game state classes to use. Manages chapter transitions, win/loss/
 * death routing, and coordinates with the narrative system for story progression.
 *
 * Server-authoritative. Extends AGameModeBase for replication support.
 *
 * Note: PlayerControllerClass, PlayerStateClass, and GameStateClass are
 * inherited from AGameModeBase — do not redeclare (UHT forbids shadowing).
 * Set them in your BP child's Class Defaults.
 */
UCLASS(Blueprintable)
class PG_FRAMEWORK_API AGM_CoreGameMode : public AGameModeBase
{
	GENERATED_BODY()

public:
	AGM_CoreGameMode();

	// ========================================================================
	// Chapter Management
	// ========================================================================

	/** The currently active chapter GameplayTag. */
	UPROPERTY(BlueprintReadOnly, Category = "Framework|Narrative")
	FGameplayTag CurrentChapterTag;

	/**
	 * Transitions the game to a new chapter.
	 * Server-authoritative. Sets phase to Loading, opens the chapter level,
	 * then restores InGame phase on load complete.
	 */
	UFUNCTION(BlueprintCallable, Category = "Framework|Narrative")
	void TransitionToChapter(FGameplayTag ChapterTag);

	// ========================================================================
	// Death Handling
	// ========================================================================

	/**
	 * Handles player death. Called by BPC_DeathHandlingSystem.
	 * Idempotent — safe to call multiple times.
	 */
	UFUNCTION(BlueprintCallable, Category = "Framework|Death")
	void HandlePlayerDead(AController* DeadController);

	// ========================================================================
	// Ending / Game Over
	// ========================================================================

	/**
	 * Triggers a specific ending condition.
	 * Passes the ending tag to BPC_EndingAccumulator for accumulation logic.
	 */
	UFUNCTION(BlueprintCallable, Category = "Framework|Narrative")
	void TriggerEnding(FGameplayTag EndingTag);

	// ========================================================================
	// Pause Control
	// ========================================================================

	/** Runtime flag — menu widgets check this before pausing. False during cutscenes/death. */
	UPROPERTY(BlueprintReadOnly, Category = "Framework|State")
	bool bPauseAllowed = true;

	// ========================================================================
	// Event Dispatchers
	// ========================================================================

	UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
	FOnChapterTransition OnChapterTransition;

	UPROPERTY(BlueprintAssignable, Category = "Framework|Events")
	FOnGameOverTriggered OnGameOverTriggered;

	// ========================================================================
	// Overrides
	// ========================================================================

	virtual void InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) override;
	virtual void BeginPlay() override;

protected:
	/** Cached reference to the framework GameInstance. */
	UPROPERTY()
	TObjectPtr<UGI_GameFramework> CachedFramework;

	/** Server-side: performs the actual level transition for a chapter. */
	void ServerTransitionToChapter(FGameplayTag ChapterTag);

	/** Called when the chapter level finishes loading. */
	void OnChapterLevelLoaded(FGameplayTag ChapterTag);
};
