# test-h3-native.R
# Tests for native H3 C backend wrappers

# =============================================================================
# latLngToCell / cellToLatLng round-trip
# =============================================================================

test_that("cpp_h3_latLngToCell returns valid hex strings", {
  cells <- cpp_h3_latLngToCell(c(16.37, 2.35), c(48.21, 48.86), 5L)
  expect_true(is.character(cells))
  expect_equal(length(cells), 2)
  expect_true(all(nchar(cells) == 15))  # H3 hex strings are 15 chars
})

test_that("cpp_h3_latLngToCell handles NA inputs", {
  cells <- cpp_h3_latLngToCell(c(16.37, NA), c(48.21, 48.86), 5L)
  expect_false(is.na(cells[1]))
  expect_true(is.na(cells[2]))
})

test_that("latLngToCell → cellToLatLng round-trip is close", {
  lon <- c(16.37, -73.99, 139.69)
  lat <- c(48.21, 40.75, 35.69)
  cells <- cpp_h3_latLngToCell(lon, lat, 8L)
  centers <- cpp_h3_cellToLatLng(cells)

  for (i in seq_along(lon)) {
    expect_true(abs(centers$lon[i] - lon[i]) < 0.1)
    expect_true(abs(centers$lat[i] - lat[i]) < 0.1)
  }
})

# =============================================================================
# isValidCell
# =============================================================================

test_that("cpp_h3_isValidCell validates correctly", {
  cells <- cpp_h3_latLngToCell(c(0, 10), c(45, 50), 5L)
  valid <- cpp_h3_isValidCell(cells)
  expect_true(all(valid))

  invalid <- cpp_h3_isValidCell(c("garbage", "0000000000000000"))
  expect_false(any(invalid))
})

test_that("cpp_h3_isValidCell handles NA", {
  result <- cpp_h3_isValidCell(c("851e15b7fffffff", NA))
  expect_true(result[1])
  expect_true(is.na(result[2]))
})

# =============================================================================
# cellToParent / cellToChildren
# =============================================================================

test_that("cpp_h3_cellToParent returns coarser cell", {
  cell <- cpp_h3_latLngToCell(0, 45, 8L)
  parent <- cpp_h3_cellToParent(cell, 5L)
  expect_true(is.character(parent))
  expect_equal(length(parent), 1)
  expect_false(parent == cell)
})

test_that("cpp_h3_cellToChildren returns 7 children", {
  cell <- cpp_h3_latLngToCell(0, 45, 5L)
  children <- cpp_h3_cellToChildren(cell, 6L)
  expect_true(is.list(children))
  expect_equal(length(children[[1]]), 7)
  expect_true(all(cpp_h3_isValidCell(children[[1]])))
})

# =============================================================================
# cellToBoundary
# =============================================================================

test_that("cpp_h3_cellToBoundary returns closed rings", {
  cell <- cpp_h3_latLngToCell(0, 45, 5L)
  bndry <- cpp_h3_cellToBoundary(cell)
  ring <- bndry[[1]]
  expect_true(is.matrix(ring))
  expect_equal(ncol(ring), 2)
  expect_equal(ring[1, ], ring[nrow(ring), ])  # closed ring
  expect_true(nrow(ring) == 7)  # 6 hex verts + 1 closing
})

# =============================================================================
# polygonToCells
# =============================================================================

test_that("cpp_h3_polygonToCells fills a bounding box", {
  bbox <- matrix(c(16, 48, 17, 48, 17, 49, 16, 49, 16, 48),
                 ncol = 2, byrow = TRUE)
  cells <- cpp_h3_polygonToCells(bbox, 5L)
  expect_true(length(cells) > 0)
  expect_true(all(cpp_h3_isValidCell(cells)))
})

# =============================================================================
# cellAreaKm2
# =============================================================================

test_that("cpp_h3_cellAreaKm2 returns positive areas", {
  cells <- cpp_h3_latLngToCell(c(0, 0), c(0, 80), 5L)
  areas <- cpp_h3_cellAreaKm2(cells)
  expect_true(all(areas > 0))
  # Areas should differ (H3 is not equal-area)
  expect_false(areas[1] == areas[2])
})

test_that("cpp_h3_cellAreaKm2 magnitude is reasonable for res 5", {
  cell <- cpp_h3_latLngToCell(0, 45, 5L)
  area <- cpp_h3_cellAreaKm2(cell)
  # H3 res 5 avg area is ~252.9 km^2
  expect_true(area > 200 && area < 300)
})
