#include "to_array.h"
#include "../tensor.h"
#include "../utils.h"
#include <torch/torch.h>

namespace TensorOps {

Napi::Value ToArray(Tensor* self, const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();

  // Flatten and convert to array
  torch::Tensor flat = self->tensor.flatten().cpu().contiguous();

  Napi::Array arr = Napi::Array::New(env, flat.numel());

  auto dtype = flat.scalar_type();

  if (dtype == torch::kFloat32) {
    auto accessor = flat.accessor<float, 1>();
    for (int64_t i = 0; i < flat.numel(); i++) {
      arr[i] = Napi::Number::New(env, accessor[i]);
    }
  } else if (dtype == torch::kFloat64) {
    auto accessor = flat.accessor<double, 1>();
    for (int64_t i = 0; i < flat.numel(); i++) {
      arr[i] = Napi::Number::New(env, accessor[i]);
    }
  } else if (dtype == torch::kInt32) {
    auto accessor = flat.accessor<int32_t, 1>();
    for (int64_t i = 0; i < flat.numel(); i++) {
      arr[i] = Napi::Number::New(env, accessor[i]);
    }
  } else if (dtype == torch::kInt64) {
    auto accessor = flat.accessor<int64_t, 1>();
    for (int64_t i = 0; i < flat.numel(); i++) {
      arr[i] = Napi::Number::New(env, accessor[i]);
    }
  } else {
    // Fallback: convert to float32
    flat = flat.to(torch::kFloat32);
    auto accessor = flat.accessor<float, 1>();
    for (int64_t i = 0; i < flat.numel(); i++) {
      arr[i] = Napi::Number::New(env, accessor[i]);
    }
  }

  return arr;
}

}  // namespace TensorOps
