/**
 * FreeExile High-Performance Native Simulation Core FFI Bridge (C++20 / AVX2).
 * Exposes C FFI symbols for Python orchestration (ctypes) and cluster integration.
 * Delegates 100% of spatial hashing, SIMD displacement, and AOI indexing to ZoneServer.
 */

#include <cstdint>
#include <mutex>
#include "world/ZoneServer.hpp"

#if defined(_WIN32) || defined(_MSC_VER)
#define EXPORT_API extern "C" __declspec(dllexport)
#else
#define EXPORT_API extern "C" __attribute__((visibility("default")))
#endif

// Global ZoneServer simulation core instance and mutex for worker shard
static FreeExile::ZoneServer g_engine(64.0f);
static std::mutex g_engine_mutex;

EXPORT_API void engine_init(float cell_size) {
    std::lock_guard<std::mutex> lock(g_engine_mutex);
    g_engine.reset(cell_size > 0.0f ? cell_size : 64.0f);
}

EXPORT_API int32_t engine_add_entity(
    int32_t entity_id,
    float x,
    float y,
    float z,
    float move_speed,
    float collision_radius,
    float hp
) {
    std::lock_guard<std::mutex> lock(g_engine_mutex);
    return g_engine.add_entity(entity_id, x, y, z, move_speed, collision_radius, hp);
}

EXPORT_API void engine_set_velocity(int32_t entity_idx, float vx, float vy) {
    std::lock_guard<std::mutex> lock(g_engine_mutex);
    g_engine.set_move_vector(entity_idx, vx, vy);
}

EXPORT_API void engine_set_evasion(int32_t entity_idx, bool is_evading) {
    std::lock_guard<std::mutex> lock(g_engine_mutex);
    g_engine.trigger_phantom_evasion(entity_idx, is_evading);
}

EXPORT_API void engine_step_tick(float dt) {
    std::lock_guard<std::mutex> lock(g_engine_mutex);
    g_engine.step_tick(dt);
}

EXPORT_API int32_t engine_query_aoi(
    float center_x,
    float center_y,
    int32_t radius_cells,
    int32_t* out_entity_ids,
    int32_t max_results
) {
    std::lock_guard<std::mutex> lock(g_engine_mutex);
    return g_engine.query_aoi(center_x, center_y, radius_cells, out_entity_ids, max_results);
}

EXPORT_API int32_t engine_get_entity_count() {
    std::lock_guard<std::mutex> lock(g_engine_mutex);
    return g_engine.get_count();
}

EXPORT_API void engine_get_entity_pos(int32_t idx, float* out_x, float* out_y, float* out_z) {
    std::lock_guard<std::mutex> lock(g_engine_mutex);
    if (!g_engine.get_entity_pos(idx, out_x, out_y, out_z)) {
        if (out_x) *out_x = 0.0f;
        if (out_y) *out_y = 0.0f;
        if (out_z) *out_z = 0.0f;
    }
}
