#pragma once
#include "VoxelTypes.h"
#include <vector>
#include <cstdint>

namespace voxel {

class VoxelWorld;

// ── Toping mesh vertex (position + normal) ──────────────────────
struct TopingVertex {
    float px, py, pz;   // position in voxel-local space [0,1]³
    float nx, ny, nz;   // normal
};

// ── Reference to a slice of vertices in the shared pool ─────────
struct MeshSlice {
    uint32_t offset;     // first vertex index in TopingSystem::vertices_
    uint32_t count;      // number of vertices (multiple of 3)
};

// ── Toping definition (one per decorative type) ─────────────────
// Each def targets a specific material + face, and provides 16
// mesh variants indexed by a 4-bit adjacency bitmask.
//
// Adjacency bitmask (for FACE_POS_Y):
//   bit 0 = +X neighbor has same material AND exposed +Y face
//   bit 1 = -X neighbor has same material AND exposed +Y face
//   bit 2 = +Z neighbor has same material AND exposed +Y face
//   bit 3 = -Z neighbor has same material AND exposed +Y face
//
// A SET bit means the neighbor IS present → no bevel on that edge.
// An UNSET bit means the edge is "open" → bevel strip generated.
struct TopingDef {
    uint8_t  materialID;       // voxel material that triggers this toping
    uint8_t  face;             // Face enum (FACE_POS_Y, etc.)
    uint8_t  priority;         // higher priority topings generate bevels over lower ones at boundaries
    float    height;           // bevel peak height (voxel units)
    float    width;            // bevel inward extent (voxel units)
    int      segments;         // subdivisions per edge strip (1=smooth, 3+=bumpy)
    MeshSlice variants[16];    // indexed by adjacency bitmask
};

// ── Placed toping instance ──────────────────────────────────────
struct TopingInstance {
    float    wx, wy, wz;      // world position of the source voxel (integer coords)
    uint16_t topingType;       // index into TopingSystem::defs_
    uint16_t variant;          // adjacency bitmask (0-15)
};

// ── Toping System ───────────────────────────────────────────────
// Manages toping definitions, procedural mesh generation, and
// instance collection from the voxel world.
//
// Phase 4.1: data structures + mesh gen + collection (no rendering).
// Phase 4.2 will upload vertices_ to a GPU vertex buffer and
// instances_ to an instance buffer for instanced drawing.
class TopingSystem {
public:
    void initialize();
    void collectInstances(const VoxelWorld& world);
    void collectInstancesParallel(const VoxelWorld& world);

    // Accessors for Phase 4.2 GPU upload
    const std::vector<TopingVertex>&  getVertices()  const { return vertices_; }
    const std::vector<TopingInstance>& getInstances() const { return instances_; }
    const std::vector<TopingDef>&     getDefs()      const { return defs_; }

    size_t getDefCount()      const { return defs_.size(); }
    size_t getInstanceCount() const { return instances_.size(); }
    size_t getVertexCount()   const { return vertices_.size(); }

private:
    void registerDefs();
    void generateMeshes();
    void generateVariant(TopingDef& def, uint8_t bitmask);
    void generateStoneVariant(TopingDef& def, uint8_t bitmask);
    void generateGrassVariant(TopingDef& def, uint8_t bitmask);

    std::vector<TopingDef>      defs_;
    std::vector<TopingVertex>   vertices_;   // shared vertex pool for all types/variants
    std::vector<TopingInstance>  instances_;  // collected per frame/update
};

} // namespace voxel
