#pragma once

#include <state/gamestate.hpp>
#include <object/entity.hpp>
#include <utils.hpp>
#include <thread>
#include <mutex>
#include <chrono>
#include <functional>
#include <object/camera.hpp>
#include <game/input.hpp>
#include <unordered_map>
#include <memory>

namespace Game {
    using clock = std::chrono::steady_clock;
    
    class GameManager {
        public:
            GameManager() { LOG("Created GameManager"); };
            DISABLE_COPY_AND_MOVE(GameManager);
            ~GameManager() = default;

            // Start the game logic slave thread, which will update the gamestate and entities; Run as jthread
            void run(std::stop_token stopToken);
            void setTargetUpdatesPerSecond(int target) { mTargetUpdatesPerSecond = target; }
            int getTargetUpdatesPerSecond() { return mTargetUpdatesPerSecond; }
            
            static void setSharedData(const std::string& key, std::string data);
            static std::string getSharedData(const std::string& key);
            static void removeSharedData(const std::string& key);

        private:
            int mTargetUpdatesPerSecond = TARGET_UPDATE_RATE;
            clock::time_point mLastUpdate;
            static std::unordered_map<std::string, std::string> mSharedStrings;
    };
}