#ifndef __ENGINE_H__
#define __ENGINE_H__

#include <SDL2/SDL.h>
#include <imgui.h>
#include <imgui_impl_sdl2.h>
#include <imgui_impl_sdlrenderer2.h>
#include <entt/entt.hpp>
#include <sol/sol.hpp>
#include "EngineConfig.h"
#include "states/StateManager.h"
#include <pybind11/embed.h>
#include "ui/PythonConsole.h"
#include "tiles/TileMapManager.h"

namespace py = pybind11;

class Engine
{
public:
    Engine();
    ~Engine();
    void Run();
    
    // Getters / Setters
    SDL_Renderer* GetRenderer() const { return renderer; }
    SDL_Window*   GetWindow()   const { return window; }
    bool          IsRunning()   const { return isRunning; }
    void          StopRunning()       { isRunning = false; }

    static Engine& Get(); // Singleton accessor

    // Python stuff
    void RunPythonScript(const std::string& filename);
    
    // StateManager
    StateManager  stateManager;
    pybind11::list GetStateStack();
    void PrintStates();
    StateManager& GetStateManager();
    const StateManager& GetStateManager() const;
    
    // Safe State transition
    void RequestStateChange(std::unique_ptr<BaseState> newState);
    void RequestPopState();
    
    // TileMapManager
    TileMapManager& GetTileMapManager() { return tileMapManager; }
    const TileMapManager& GetTileMapManager() const { return tileMapManager; }
    
    // Debug
    void DebugInfo();
    
private:
    SDL_Window*   window    = nullptr;
    SDL_Renderer* renderer  = nullptr;
    bool          isRunning = true;

    SDL_Rect camera = { 0, 0, EngineConfig::DEFAULT_WINDOW_WIDTH, EngineConfig::DEFAULT_WINDOW_HEIGHT };
    
    // General functions
    void InitSDL();
    void InitImGui();
    void InitAudio();
    void HandleEvents();
    void Update(float dt);
    void Render();

    // Python support
    void InitPython();
    void ShutdownPython();
    static Engine* s_instance;
    PythonConsole pythonConsole;

    // StateManager
    std::unique_ptr<BaseState> pendingNewState = nullptr;
    bool pendingPop = false;
    
    // TileMapManager
    TileMapManager tileMapManager;

};

#endif