#pragma once
#include <cstdint>

// SpatialHash — grid espacial para hit-testing de nodos en grafos.
// Permite buscar el nodo mas cercano a una posicion en O(1) amortizado.
struct SpatialHash {
    float cell_size;
    int   table_size;    // numero de buckets en la tabla hash

    // Almacenamiento interno (flat arrays)
    int* buckets;        // table_size entradas, cada una apunta al primer entry de la cadena
    int* entries;        // pares [node_index, next]: entries[2*i] = node_idx, entries[2*i+1] = next
    int  entry_count;
    int  entry_capacity;

    SpatialHash(float cell_size = 20.0f, int table_size = 4096);
    ~SpatialHash();

    SpatialHash(const SpatialHash&) = delete;
    SpatialHash& operator=(const SpatialHash&) = delete;

    // Reconstruye la tabla desde arrays de posiciones y tamaños de nodos.
    // xs[i], ys[i]: posicion del nodo i. sizes[i]: radio del nodo i.
    void build(const float* xs, const float* ys, const float* sizes, int count);

    // Busca el punto mas cercano dentro de (qx, qy) con radio de busqueda dado.
    // Descuenta el tamaño del nodo (circulo): distancia efectiva = dist(centro) - size.
    // Retorna el indice del nodo, o -1 si no hay ninguno.
    // Si out_dist es no-nulo, escribe la distancia al nodo encontrado.
    int query_nearest(float qx, float qy, float radius, float* out_dist = nullptr) const;

    // Busca todos los puntos dentro del radio. Escribe indices en out[].
    // Retorna el numero de nodos encontrados (hasta max_out).
    int query_radius(float qx, float qy, float radius, int* out, int max_out) const;

private:
    // Hash de coordenadas de celda enteras a indice de bucket.
    int cell_hash(int cx, int cy) const;
};
