#pragma once
#include <CGAL/Surface_mesh.h>
#include <Eigen/Dense>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>


namespace mesh_utils {
template <typename Kernel>
void cgal_to_eigen(CGAL::Surface_mesh<typename Kernel::Point_3>& mesh,
                   Eigen::MatrixXd& V, Eigen::MatrixXi& F) {
  
 CGAL::Polygon_mesh_processing::triangulate_faces(mesh);

  V.resize(mesh.num_vertices(), 3);
  F.resize(mesh.num_faces(), 3);

  for (auto v : mesh.vertices()) {
    auto p = mesh.point(v);
    V.row(v.idx()) << p.x(), p.y(), p.z();
  }

  Eigen::Index face_idx = 0;
  for (auto f : mesh.faces()) {
    int vertex_count = 0;
    for (auto h : CGAL::halfedges_around_face(mesh.halfedge(f), mesh)) {
      auto v = mesh.target(h);
      F(face_idx, vertex_count) = v.idx();
      ++vertex_count;
    }
    face_idx++;
  }
}
template <typename Kernel>
void simple_visualize_mesh(Eigen::MatrixXd& V, Eigen::MatrixXi& F) {
  igl::opengl::glfw::Viewer viewer;
  viewer.data().set_mesh(V, F);
  viewer.launch();
}
// Zero-copy map for V (optional)
template <typename Kernel>
Eigen::Map<Eigen::Matrix<double, Eigen::Dynamic, 3, Eigen::RowMajor>>
get_vertex_map(CGAL::Surface_mesh<typename Kernel::Point_3>& mesh) {
  auto& points = mesh.points();
  double* data = reinterpret_cast<double*>(&points[0][0]);
  return {data, static_cast<Eigen::Index>(points.size()), 3};
}
}  // namespace
