#pragma once

#include <string>
#include <types/base/types.h>

namespace extra2d {

/**
 * @brief 平台类型枚举
 */
enum class PlatformType { 
    Auto = 0, 
    PC, 
    Switch 
};

/**
 * @brief 应用程序配置
 */
struct AppConfig {
    std::string title = "Extra2D Application";
    int32 width = 1280;
    int32 height = 720;
    bool fullscreen = false;
    bool resizable = true;
    bool vsync = true;
    int32 fpsLimit = 0;
    int32 glMajor = 3;
    int32 glMinor = 3;
    PlatformType platform = PlatformType::Auto;
    bool enableCursors = true;
    bool enableDpiScale = false;
};

/**
 * @brief 应用程序主控类
 * 
 * 管理应用程序生命周期、窗口和主循环
 */
class Application {
public:
    /**
     * @brief 获取单例实例
     */
    static Application& instance();

    Application(const Application&) = delete;
    Application& operator=(const Application&) = delete;

    /**
     * @brief 初始化应用程序
     */
    bool init(const AppConfig& config);
    
    /**
     * @brief 关闭应用程序
     */
    void shutdown();
    
    /**
     * @brief 运行主循环
     */
    void run();
    
    /**
     * @brief 请求退出
     */
    void quit();

    /**
     * @brief 暂停应用
     */
    void pause();
    
    /**
     * @brief 恢复应用
     */
    void resume();
    
    /**
     * @brief 是否暂停
     */
    bool isPaused() const { return paused_; }
    
    /**
     * @brief 是否运行中
     */
    bool isRunning() const { return running_; }

    /**
     * @brief 获取帧时间
     */
    float deltaTime() const { return deltaTime_; }
    
    /**
     * @brief 获取总运行时间
     */
    float totalTime() const { return totalTime_; }
    
    /**
     * @brief 获取当前 FPS
     */
    int32 fps() const { return currentFps_; }

    /**
     * @brief 获取配置
     */
    const AppConfig& getConfig() const { return config_; }

private:
    Application() = default;
    ~Application();

    void mainLoop();
    void update();

    AppConfig config_;

    bool initialized_ = false;
    bool running_ = false;
    bool paused_ = false;
    bool shouldQuit_ = false;

    float deltaTime_ = 0.0f;
    float totalTime_ = 0.0f;
    double lastFrameTime_ = 0.0;
    int32 frameCount_ = 0;
    float fpsTimer_ = 0.0f;
    int32 currentFps_ = 0;
};

#define APP extra2d::Application::instance()

} // namespace extra2d
