test_that("spatial simulation keeps returned coordinates in bounds and warns on discarded offspring", {
  set.seed(1)
  catalog <- expect_warning(
    simulateETAS(5, 0.8, 0, 0.5, 2.2, 2.5, 3, 2,
                 sigma2x = 1, sigma2y = 100,
                 xmin = 0, xmax = 1, ymin = 0, ymax = 1),
    "Discarded [0-9]+ proposed offspring outside the spatial window",
    fixed = FALSE
  )
  expect_true(all(catalog$locs$xs >= 0 & catalog$locs$xs <= 1))
  expect_true(all(catalog$locs$ys >= 0 & catalog$locs$ys <= 1))
  expect_true(all(catalog$branching >= 0))
  expect_true(all(vapply(seq_along(catalog$branching), function(i) {
    catalog$branching[i] == 0 || catalog$branching[i] < i
  }, logical(1))))
})

test_that("estimateETAS accepts spatial initval and burnin zero", {
  ts <- c(0.2, 0.8, 1.4, 2.0)
  ms <- c(3.0, 3.2, 3.1, 3.4)
  xs <- c(0.1, 0.3, 0.7, 0.9)
  ys <- c(0.1, 0.4, 0.5, 0.8)
  init_t <- c(0.4, 0.2, 0.3, 0.5, 2.0)
  init_s <- c(init_t, 0.4, 0.7)

  temporal <- estimateETAS(ts, ms, 3, maxTime = 2.5,
                           sims = 2, burnin = 0, initval = init_t)
  expect_s3_class(temporal, "data.frame")
  expect_equal(nrow(temporal), 2)

  spatial <- estimateETAS(ts, ms, 3, maxTime = 2.5, xs = xs, ys = ys,
                          area = 1, sims = 2, burnin = 0,
                          initval = init_s,
                          sigma2_prior_shape = 3,
                          sigma2x_prior_rate = 0.02,
                          sigma2y_prior_rate = 0.02)
  expect_s3_class(spatial, "data.frame")
  expect_equal(nrow(spatial), 2)
  expect_equal(ncol(spatial), 7)
  expect_equal(attr(spatial, "sigma2_prior")$shape, 3)
  expect_equal(attr(spatial, "sigma2_prior")$rate_x, 0.02)
  expect_equal(attr(spatial, "sigma2_prior")$rate_y, 0.02)
})

test_that("wrong initval lengths and invalid fitting inputs are rejected", {
  ts <- c(0.2, 0.8, 1.4, 2.0)
  ms <- c(3.0, 3.2, 3.1, 3.4)
  xs <- c(0.1, 0.3, 0.7, 0.9)
  ys <- c(0.1, 0.4, 0.5, 0.8)

  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 2.5, initval = c(0.4, 0.2)),
    "initval must have length 5"
  )
  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 2.5, xs = xs, ys = ys, area = 1,
                 initval = c(0.4, 0.2, 0.3, 0.5, 2.0)),
    "initval must have length 7"
  )
  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 2.5,
                 initval = c(0.4, 0.2, 0.3, 0, 2.0)),
    "c must be positive"
  )
  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 2.5,
                 initval = c(0.4, 0.2, 0.3, 0.5, 1.0)),
    "p must be greater than 1"
  )
  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 1.0,
                 initval = c(0.4, 0.2, 0.3, 0.5, 2.0)),
    "maxTime must be greater than or equal to max\\(ts\\)"
  )
  expect_error(
    estimateETAS(ts, c(2.9, ms[-1]), 3, maxTime = 2.5,
                 initval = c(0.4, 0.2, 0.3, 0.5, 2.0)),
    "all magnitudes in ms must be greater than or equal to M0"
  )
  expect_error(
    estimateETAS(rev(ts), ms, 3, maxTime = 2.5,
                 initval = c(0.4, 0.2, 0.3, 0.5, 2.0)),
    "ts must be sorted"
  )
  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 2.5, xs = xs, ys = ys, area = 1,
                 initval = c(0.4, 0.2, 0.3, 0.5, 2.0, 0, 0.7)),
    "initval\\[6\\] must be positive"
  )
})

test_that("simulation parameter validation rejects invalid parameters", {
  expect_error(simulateETAS(0.1, 0.2, 0.3, 0, 2, 2.5, 3, 1),
               "c must be positive")
  expect_error(simulateETAS(0.1, 0.2, 0.3, 0.5, 1, 2.5, 3, 1),
               "p must be greater than 1")
  expect_error(simulateETAS(0.1, 0.2, 0.3, 0.5, 2, 2.5, 3, 1,
                            sigma2x = 0, sigma2y = 1,
                            xmin = 0, xmax = 1, ymin = 0, ymax = 1),
               "sigma2x must be positive")
})

test_that("spatial prior validation handles invalid and degenerate defaults", {
  ts <- c(0.2, 0.8, 1.4, 2.0)
  ms <- c(3.0, 3.2, 3.1, 3.4)
  ys <- c(0.1, 0.4, 0.5, 0.8)
  init_s <- c(0.4, 0.2, 0.3, 0.5, 2.0, 0.4, 0.7)

  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 2.5, xs = c(1, 1, 1, 1), ys = ys,
                 area = 1, sims = 2, burnin = 0, initval = init_s),
    "sigma2x_prior_rate must be provided"
  )
  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 2.5,
                 xs = c(0.1, 0.3, 0.7, 0.9), ys = ys,
                 area = 1, sims = 2, burnin = 0, initval = init_s,
                 sigma2_prior_shape = 2),
    "sigma2_prior_shape must be greater than 2"
  )
  expect_error(
    estimateETAS(ts, ms, 3, maxTime = 2.5,
                 xs = c(0.1, 0.3, 0.7, 0.9), ys = ys,
                 area = 1, sims = 2, burnin = 0, initval = init_s,
                 sigma2x_prior_rate = -1),
    "sigma2x_prior_rate must be positive"
  )
})
