// Constants related to the arena dimensions
constexpr float BACK_WALL_Y = 5120.0f;
constexpr float NEG_BACK_WALL_Y = -5120.0f;     // Negative back wall at y = -5120.0f
constexpr float MAX_BACKWALL_Y = 5100.0f;       // New threshold as per user request
constexpr float BOOST_ACCEL_POS = 1000.0f;      // Boost acceleration towards positive back wall (units/s²)
constexpr float BOOST_ACCEL_NEG = -1000.0f;     // Boost acceleration towards negative back wall (units/s²)

float calculateTimeToBackWalls(const PlayerData& player) {
    const Vec& pos = player.phys.pos;
    const Vec& vel = player.phys.vel;

    // Initialize minTime to infinity
    float minTime = std::numeric_limits<float>::infinity();

    // Check if the player is already at or beyond the positive back wall
    if (pos.y >= BACK_WALL_Y) {
        return 0.0f; // Immediate collision with positive back wall
    }

    // Check if the player is already at or beyond the negative back wall
    if (pos.y <= NEG_BACK_WALL_Y) {
        return 0.0f; // Immediate collision with negative back wall
    }

    // ** Calculate Time to Positive Back Wall (y = BACK_WALL_Y) **
    if (vel.y > EPSILON) { // Player is moving towards the positive back wall
        float a = 0.5f * BOOST_ACCEL_POS;          // Acceleration coefficient (positive)
        float b = vel.y;                           // Initial velocity towards positive y
        float c = pos.y - BACK_WALL_Y;            // Initial position offset from positive back wall

        // Quadratic equation: a*t^2 + b*t + c = 0
        float discriminant = b * b - 4.0f * a * c;

        if (discriminant >= 0.0f) { // Real solutions exist
            float sqrtD = std::sqrt(discriminant);
            float t1 = (-b + sqrtD) / (2.0f * a);
            float t2 = (-b - sqrtD) / (2.0f * a);

            // Select the smallest positive time
            if (t1 > EPSILON && t1 < minTime) {
                minTime = t1;
            }
            if (t2 > EPSILON && t2 < minTime) {
                minTime = t2;
            }
        }
    }

    // ** Calculate Time to Negative Back Wall (y = NEG_BACK_WALL_Y) **
    if (vel.y < -EPSILON) { // Player is moving towards the negative back wall
        float a = 0.5f * BOOST_ACCEL_NEG;         // Acceleration coefficient (negative)
        float b = vel.y;                           // Initial velocity towards negative y
        float c = pos.y - NEG_BACK_WALL_Y;        // Initial position offset from negative back wall

        // Quadratic equation: a*t^2 + b*t + c = 0
        float discriminant = b * b - 4.0f * a * c;

        if (discriminant >= 0.0f) { // Real solutions exist
            float sqrtD = std::sqrt(discriminant);
            float t1 = (-b + sqrtD) / (2.0f * a);
            float t2 = (-b - sqrtD) / (2.0f * a);

            // Select the smallest positive time
            if (t1 > EPSILON && t1 < minTime) {
                minTime = t1;
            }
            if (t2 > EPSILON && t2 < minTime) {
                minTime = t2;
            }
        }
    }

    return minTime;
}

// Constants related to the arena dimensions and gravity
constexpr float FLOOR_Z = 18.0f;      // Assuming the floor is at z = 0
constexpr float BOOST_ACCEL_DOWN = -1000.0f;

float calculateTimeToFloor(const PlayerData& player) {
    const Vec& pos = player.phys.pos;
    const Vec& vel = player.phys.vel;

    // ** Immediate Floor Proximity Check **
    if (pos.z <= FLOOR_Z) {
        return 0.0f; // Player is already at or below the floor
    }

    // ** Calculate Total Downward Acceleration **
    // Sum of gravity and boosting acceleration (both downward, hence negative)
    float totalAccel = GRAVITY_Z + BOOST_ACCEL_DOWN; // e.g., -650 + (-1000) = -1650 units/s²

    // ** Define Quadratic Coefficients **
    // Using the kinematic equation: 0.5 * a * t² + v₀ * t + s₀ = 0
    float a = 0.5f * totalAccel;    // Acceleration coefficient (negative)
    float b = vel.z;                 // Initial vertical velocity
    float c = pos.z;                 // Initial position above the floor

    // ** Calculate Discriminant **
    float discriminant = b * b - 4.0f * a * c;

    // ** Check for Real Solutions **
    if (discriminant < 0.0f) {
        return std::numeric_limits<float>::infinity(); // No real solution; player won't reach the floor
    }

    // ** Calculate the Two Possible Times Using the Quadratic Formula **
    float sqrtD = std::sqrt(discriminant);
    float t1 = (-b - sqrtD) / (2.0f * a); // Smaller time
    float t2 = (-b + sqrtD) / (2.0f * a); // Larger time

    // ** Select the Positive and Smaller Time **
    float timeToFloor = std::numeric_limits<float>::infinity();

    if (t1 > 0.0f) {
        timeToFloor = t1;
    }
    if (t2 > 0.0f && t2 < timeToFloor) {
        timeToFloor = t2;
    }

    return timeToFloor;
}
 make this be liek the others // Constants related to the arena dimensions
constexpr float SIDE_WALL_X = 4096.0f;
constexpr float CLOSE_DISTANCE = 10.0f;        // Distance threshold for proximity to the walls
constexpr float NEAR_WALL_DISTANCE = 4077.0f;  // Threshold for x close to the wall
constexpr float Z_THRESHOLD = 256.0f;          // Threshold for z axis proximity to the ground
constexpr float EPSILON = 1e-3f;               // Small value for floating point comparison

// Movement-related constants
constexpr float DIST_REACH_THRESH = 80.0f;
constexpr float STEP_INTERVAL = 1.0f / 60.0f;    // Time step (e.g., 60 FPS)
constexpr float FLIP_FORCE = 495.0f;
constexpr float AIR_ACCEL = 66.66667f;
constexpr float BOOST_ACCEL_AIR = 1058.33333f;
constexpr float MAX_TOTAL_SPEED = 2300.0f;
constexpr float BRAKE_ACCEL = 3500.0f;
constexpr float BOOST_ACCEL_GROUND = 991.66667f;
constexpr float DRIVE_ACCEL = 1600.0f;
constexpr float MAX_DRIVE_SPEED = 1410.0f;
constexpr float GRAVITY_Z = -650.0f; // Example gravity value, adjust as needed

float calculateTimeToSideWalls(const PlayerData& player) {
    float current_x = player.phys.pos.x;
    float current_z = player.phys.pos.z;        // Player's z coordinate
    float velocity_x = player.phys.vel.x;

    // Check if the player's z is below the threshold (under 256 units)
    if (current_z <= Z_THRESHOLD) {
        return 0.0f; // Player is too close to the ground
    }

    // Check if the player is very close to the positive or negative side wall (within ±4077 units)
    if (std::abs(current_x) >= NEAR_WALL_DISTANCE && std::abs(current_x) <= SIDE_WALL_X) {
        return 0.0f; // Player is very close to the side walls
    }

    // Initialize time to infinity
    float timeToWall = std::numeric_limits<float>::infinity();

    // Function to simulate movement over time steps
    auto simulateMovement = [&](float initial_pos, float initial_vel, float wall_pos) -> float {
        float pos = initial_pos;
        float vel = initial_vel;
        float time = 0.0f;

        while (time < 10.0f) { // Arbitrary large time limit to prevent infinite loops
            // Determine acceleration based on current velocity
            if (std::abs(vel) < MAX_TOTAL_SPEED && time == 0.0f) {
                // Apply flip force if velocity is below max and at initial step
                vel += FLIP_FORCE;
            }
            if (vel < 0.0f) {
                // Decelerate if moving away from the wall
                vel += (BRAKE_ACCEL + BOOST_ACCEL_GROUND /* Assuming ground for simplicity */) * STEP_INTERVAL;
            }
            else if (vel < MAX_DRIVE_SPEED) {
                // Accelerate towards max drive speed
                vel += (DRIVE_ACCEL + BOOST_ACCEL_GROUND) * STEP_INTERVAL;
            }
            else if (vel < MAX_TOTAL_SPEED) {
                // Continue boosting towards max total speed
                vel += BOOST_ACCEL_GROUND * STEP_INTERVAL;
            }
            // Clamp velocity to max total speed
            if (vel > MAX_TOTAL_SPEED) {
                vel = MAX_TOTAL_SPEED;
            }

            // Update position
            pos += vel * STEP_INTERVAL;

            // Check for wall collision
            if ((wall_pos > 0.0f && pos >= wall_pos) || (wall_pos < 0.0f && pos <= wall_pos)) {
                // Calculate exact time of collision within the current step
                float overshoot = pos - wall_pos;
                float collided_time = STEP_INTERVAL - (overshoot / vel);
                return time + collided_time;
            }

            // Increment time
            time += STEP_INTERVAL;
        }

        return std::numeric_limits<float>::infinity(); // Did not collide within time limit
        };

    // Calculate time to positive side wall (x = +4096.0f)
    if (velocity_x > 0.0f) {
        float distanceToPositiveWall = SIDE_WALL_X - current_x;
        if (distanceToPositiveWall > 0.0f) {
            float estimatedTime = simulateMovement(current_x, velocity_x, SIDE_WALL_X);
            if (estimatedTime > 0.0f && estimatedTime < timeToWall) {
                timeToWall = estimatedTime;
            }
        }
    }
    // Calculate time to negative side wall (x = -4096.0f)
    else if (velocity_x < 0.0f) {
        float distanceToNegativeWall = (-SIDE_WALL_X) - current_x;
        if (distanceToNegativeWall < 0.0f) { // Since moving negative
            float estimatedTime = simulateMovement(current_x, velocity_x, -SIDE_WALL_X);
            if (estimatedTime > 0.0f && estimatedTime < timeToWall) {
                timeToWall = estimatedTime;
            }
        }
    }

    // At this point, timeToWall is either the time to the nearest wall or infinity

    // Additional Extrapolation Logic: Consider player reaching maximum speed
    // Assuming the player can accelerate to max speed, we can calculate the time to reach the wall faster

    // Only proceed if the current velocity is not already towards wall
    if (timeToWall == std::numeric_limits<float>::infinity()) {
        // Determine direction towards positive wall
        if (velocity_x > 0.0f) {
            float distanceToPositiveWall = SIDE_WALL_X - current_x;
            if (distanceToPositiveWall > 0.0f) {
                // Time to reach max speed
                float timeToMaxSpeed = (MAX_DRIVE_SPEED - velocity_x) / DRIVE_ACCEL;
                // Distance covered until reaching max speed
                float distanceCovered = velocity_x * timeToMaxSpeed + 0.5f * DRIVE_ACCEL * timeToMaxSpeed * timeToMaxSpeed;
                if (distanceCovered >= distanceToPositiveWall) {
                    // Player hits the wall before reaching max speed
                    float a = 0.5f * DRIVE_ACCEL;
                    float b = velocity_x;
                    float c = -distanceToPositiveWall;
                    float discriminant = b * b - 4.0f * a * c;
                    if (discriminant >= 0.0f) {
                        float sqrtD = std::sqrt(discriminant);
                        float t1 = (-b + sqrtD) / (2.0f * a);
                        float t2 = (-b - sqrtD) / (2.0f * a);
                        float t = (t1 > EPSILON) ? t1 : ((t2 > EPSILON) ? t2 : std::numeric_limits<float>::infinity());
                        if (t < timeToWall) {
                            timeToWall = t;
                        }
                    }
                }
                else {
                    // Player reaches max speed before hitting the wall
                    float remainingDistance = distanceToPositiveWall - distanceCovered;
                    float timeAtMaxSpeed = remainingDistance / MAX_DRIVE_SPEED;
                    float totalTime = timeToMaxSpeed + timeAtMaxSpeed;
                    if (totalTime < timeToWall) {
                        timeToWall = totalTime;
                    }
                }
            }
        }
        // Similar logic can be applied for negative wall direction
        else if (velocity_x < 0.0f) {
            float distanceToNegativeWall = (-SIDE_WALL_X) - current_x;
            if (distanceToNegativeWall < 0.0f) {
                float timeToMaxSpeed = (-MAX_DRIVE_SPEED - velocity_x) / (-DRIVE_ACCEL); // Adjust signs
                float distanceCovered = velocity_x * timeToMaxSpeed + 0.5f * (-DRIVE_ACCEL) * timeToMaxSpeed * timeToMaxSpeed;
                if (distanceCovered <= distanceToNegativeWall) {
                    // Player hits the wall before reaching max speed
                    float a = 0.5f * (-DRIVE_ACCEL);
                    float b = velocity_x;
                    float c = -distanceToNegativeWall;
                    float discriminant = b * b - 4.0f * a * c;
                    if (discriminant >= 0.0f) {
                        float sqrtD = std::sqrt(discriminant);
                        float t1 = (-b + sqrtD) / (2.0f * a);
                        float t2 = (-b - sqrtD) / (2.0f * a);
                        float t = (t1 > EPSILON) ? t1 : ((t2 > EPSILON) ? t2 : std::numeric_limits<float>::infinity());
                        if (t < timeToWall) {
                            timeToWall = t;
                        }
                    }
                }
                else {
                    // Player reaches max speed before hitting the wall
                    float remainingDistance = distanceToNegativeWall - distanceCovered;
                    float timeAtMaxSpeed = remainingDistance / (-MAX_DRIVE_SPEED);
                    float totalTime = timeToMaxSpeed + timeAtMaxSpeed;
                    if (totalTime < timeToWall) {
                        timeToWall = totalTime;
                    }
                }
            }
        }
    }

    return timeToWall;
}