#pragma once

#include <grove/JsonDataNode.h>
#include <nlohmann/json.hpp>
#include <memory>

namespace celuna::tests {

using json = nlohmann::json;

/**
 * @brief Simulates game time for testing modules
 *
 * Modules receive time info via process() input:
 * {
 *   "gameTime": 123.45,    // Total elapsed time in seconds
 *   "deltaTime": 0.1       // Time since last frame
 * }
 */
class TimeSimulator {
public:
    TimeSimulator() = default;

    /**
     * @brief Create input data for module.process()
     * @param deltaTime Time since last frame (default 0.1s = 10Hz)
     */
    json createInput(float deltaTime = 0.1f) {
        json input = {
            {"gameTime", m_gameTime},
            {"deltaTime", deltaTime}
        };
        m_gameTime += deltaTime;
        return input;
    }

    /**
     * @brief Create input as IDataNode
     */
    std::unique_ptr<grove::JsonDataNode> createInputNode(float deltaTime = 0.1f) {
        return std::make_unique<grove::JsonDataNode>("input", createInput(deltaTime));
    }

    /**
     * @brief Advance time without creating input
     */
    void advance(float seconds) {
        m_gameTime += seconds;
    }

    /**
     * @brief Advance time by minutes (convenience for hyperfocus tests)
     */
    void advanceMinutes(float minutes) {
        m_gameTime += minutes * 60.0f;
    }

    /**
     * @brief Set absolute time
     */
    void setTime(float time) {
        m_gameTime = time;
    }

    /**
     * @brief Get current game time
     */
    float getTime() const {
        return m_gameTime;
    }

    /**
     * @brief Reset to zero
     */
    void reset() {
        m_gameTime = 0.0f;
    }

    /**
     * @brief Simulate multiple frames
     * @param count Number of frames to simulate
     * @param deltaTime Time per frame
     */
    void simulateFrames(int count, float deltaTime = 0.1f) {
        m_gameTime += count * deltaTime;
    }

private:
    float m_gameTime = 0.0f;
};

} // namespace celuna::tests
