#pragma once

#include <vector>
#include <array>
#include <memory>
#include <SDL3/SDL.h>

// Forward declarations
class FontAtlas;
class Game;
class ScoreManager;
class Starfield;
class Starfield3D;
class LineEffect;

/**
 * GlobalState - Centralized management of application-wide state
 * 
 * Replaces global variables scattered throughout main.cpp
 * Provides controlled access to shared state between systems
 * Will eventually be replaced by proper dependency injection
 */
class GlobalState {
public:
    // Singleton access (temporary until dependency injection is implemented)
    static GlobalState& instance();

    // Initialization and cleanup
    void initialize();
    void shutdown();

    // Application state flags
    bool running = true;
    bool isFullscreen = false;
    bool musicEnabled = true;
    bool musicStarted = false;
    bool musicLoaded = false;

    // UI state flags
    bool showSettingsPopup = false;
    bool showExitConfirmPopup = false;
    int hoveredButton = -1;  // -1 = none, 0 = play, 1 = level, 2 = settings

    // Input state (will be migrated to InputManager)
    bool leftHeld = false;
    bool rightHeld = false;
    double moveTimerMs = 0.0;

    // Loading state
    double loadingProgress = 0.0;
    int currentTrackLoading = 0;
    int totalTracks = 0;
    int startLevelSelection = 0;

    // Timing
    Uint64 lastMs = 0;
    Uint64 loadStart = 0;

    // Animation state
    double logoAnimCounter = 0.0;

    // Level background caching
    int cachedLevel = -1;
    float levelFadeAlpha = 0.0f;
    float levelFadeElapsed = 0.0f;

    // Viewport and scaling
    SDL_Rect logicalVP{0, 0, 1200, 1000};  // Will use Config::Logical constants
    float logicalScale = 1.0f;
    
    // Dynamic logical dimensions (computed from window size)
    int currentLogicalWidth = 1200;
    int currentLogicalHeight = 1000;

    // Fireworks system (for menu animation)
    struct BlockParticle {
        float x = 0.0f;
        float y = 0.0f;
        float vx = 0.0f;
        float vy = 0.0f;
        float size = 0.0f;
        float life = 0.0f;
        float maxLife = 0.0f;
        SDL_Color color{255, 255, 255, 255};
        SDL_Color accentColor{255, 255, 255, 255};
        int generation = 0;
        bool hasExploded = false;
        bool crackle = false;
        float flickerSeed = 0.0f;
        bool dualColor = false;
        float colorBlendSpeed = 0.0f;
    };

    struct SparkParticle {
        float x = 0.0f;
        float y = 0.0f;
        float vx = 0.0f;
        float vy = 0.0f;
        float life = 0.0f;
        float maxLife = 0.0f;
        float thickness = 1.0f;
        SDL_Color color{255, 255, 255, 255};
    };

    struct TetrisFirework {
        std::vector<BlockParticle> particles;
        std::vector<SparkParticle> sparks;
        bool active = false;
        float originX = 0.0f;
        float originY = 0.0f;
        float elapsedMs = 0.0f;
        int nextBurst = 0;
        std::array<float, 3> burstSchedule{0.0f, 250.0f, 520.0f};
        std::array<SDL_Color, 3> burstColors{};
    };

    std::vector<TetrisFirework> fireworks;
    Uint64 lastFireworkTime = 0;
    bool pendingStaggerFirework = false;
    Uint64 nextStaggerFireworkTime = 0;
    float lastFireworkX = 0.0f;
    float lastFireworkY = 0.0f;

    // Fireworks management methods
    void updateFireworks(double frameMs);
    void createFirework(float x, float y);
    void drawFireworks(SDL_Renderer* renderer, SDL_Texture* blocksTex);

    // Logical dimensions management
    void updateLogicalDimensions(int windowWidth, int windowHeight);
    int getLogicalWidth() const { return currentLogicalWidth; }
    int getLogicalHeight() const { return currentLogicalHeight; }

    // Reset methods for different states
    void resetGameState();
    void resetUIState();
    void resetAnimationState();

private:
    GlobalState() = default;
    ~GlobalState() = default;
    GlobalState(const GlobalState&) = delete;
    GlobalState& operator=(const GlobalState&) = delete;

    bool m_initialized = false;
};

// Convenience accessors (temporary until proper dependency injection)
namespace Globals {
    inline GlobalState& state() { return GlobalState::instance(); }
    
    // Quick access to commonly used flags
    inline bool& running() { return state().running; }
    inline bool& musicEnabled() { return state().musicEnabled; }
    inline bool& showSettingsPopup() { return state().showSettingsPopup; }
    inline int& hoveredButton() { return state().hoveredButton; }
    inline double& logoAnimCounter() { return state().logoAnimCounter; }
}
