#include "Deer/Application.h"
#include <functional>
#include <thread>

namespace Deer {
    namespace Application {
        // Implemented in DeerRender/Application
        void runRender(float deltaTime);
        void resolveEvents();

        Function tickCallback;
        bool running;

        const double targetUpdateTime = 1.0 / 60.0;  // Fixed 60 FPS update
        double targetRenderTime = 1.0 / 160.0;  // User-defined render FPS

		void setTickCallback(Function _tick) {
            tickCallback = _tick;
        }

        void run() {
            running = true;

            auto previousTime = std::chrono::high_resolution_clock::now();
            double accumulatedUpdateTime = 0.0;
            double accumulatedRenderTime = 0.0;

            while (running) {
                // Time handling
                auto currentTime = std::chrono::high_resolution_clock::now();
                std::chrono::duration<double> deltaTime = currentTime - previousTime;
                previousTime = currentTime;

                accumulatedUpdateTime += deltaTime.count();
                accumulatedRenderTime += deltaTime.count();

                // Fixed Update loop (60 FPS)
                while (accumulatedUpdateTime >= targetUpdateTime) {
                    Timestep timestep = (float)targetUpdateTime;
                    accumulatedUpdateTime -= targetUpdateTime;

                    if (tickCallback)
                        tickCallback();
                    
                }
#ifdef DEER_RENDER
                if (accumulatedRenderTime >= targetRenderTime) {
                    runRender((float)targetRenderTime);
                    accumulatedRenderTime -= targetRenderTime;
                }
                resolveEvents();
#endif
                std::this_thread::sleep_for(std::chrono::milliseconds(1));
            }
        }

		void shutdown() {
            running = false;
        }
    }
}