#pragma once
// ── CS2 External C++ WebRadar — Grenade Trajectory Simulator ────────────────
// Matches C# GrenadeSimulator.cs: tick-based physics simulation for grenade
// trajectory prediction. Produces a JSON string of trajectory points.

#include "core/types.h"
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>

class GrenadeSimulator {
public:
    // ── Constants ─────────────────────────────────────────────────────────
    static constexpr float SIM_DT = 1.0f / 64.0f;       // 64 Hz physics
    static constexpr int   MAX_TICKS = 256;               // max simulation steps
    static constexpr float GRAVITY = 320.0f;              // CS2 gravity
    static constexpr float ELASTICITY = 0.45f;            // bounce loss
    static constexpr float STOP_SPEED_SQ = 2036.0f;       // squared speed to stop

    // ── Trajectory simulation ─────────────────────────────────────────────
    // Returns a JSON string of {x,y} points for the radar overlay.
    // origin = throw position, velocity = initial velocity.
    static std::string simulate_trajectory(const Vec3& origin, const Vec3& velocity) {
        Vec3 pos = origin;
        Vec3 vel = velocity;
        std::ostringstream json;
        json << std::fixed << std::setprecision(1);
        json << "[";

        bool first = true;
        for (int tick = 0; tick < MAX_TICKS; tick++) {
            // Apply gravity (only affects Z)
            vel.z -= GRAVITY * SIM_DT;

            // Air resistance (drag)
            vel.x *= 0.998f;
            vel.y *= 0.998f;
            vel.z *= 0.998f;

            // Update position
            pos.x += vel.x * SIM_DT;
            pos.y += vel.y * SIM_DT;
            pos.z += vel.z * SIM_DT;

            // Floor collision
            if (pos.z < 0) {
                pos.z = 0;
                vel.z = -vel.z * ELASTICITY;

                // Stop if bounce is negligible
                float speed_sq = vel.length_sq();
                if (speed_sq < STOP_SPEED_SQ) {
                    if (!first) json << ",";
                    json << "{\"x\":" << pos.x << ",\"y\":" << pos.y << "}";
                    break;
                }
            }

            if (!first) json << ",";
            json << "{\"x\":" << pos.x << ",\"y\":" << pos.y << "}";
            first = false;
        }

        json << "]";
        return json.str();
    }
};
