## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment  = "#>",
  eval     = FALSE
)


## -----------------------------------------------------------------------------
library(inlabru)
library(INLA)
library(sp)
library(inlaops)
library(vetiver)
library(pins)

# Synthesise some toy point data on a 10x10 domain. In a real application
# obs_sp comes from your sampling effort.
set.seed(2026)
n_obs  <- 60
obs_df <- data.frame(
  x = runif(n_obs, 0, 10),
  y = runif(n_obs, 0, 10)
)
obs_df$value <- 1 + 0.3 * obs_df$x + rnorm(n_obs, sd = 0.5)
obs_sp <- sp::SpatialPointsDataFrame(
  coords      = obs_df[, c("x", "y")],
  # Not `y`: that name is taken by a coordinate, and requests carry both.
  data        = data.frame(value = obs_df$value),
  proj4string = sp::CRS(SRS_string = "EPSG:32632")
)

# Build mesh and SPDE component (fmesher::fm_mesh_2d_inla replaces the
# deprecated INLA::inla.mesh.2d in inlabru >= 2.12).
mesh  <- fmesher::fm_mesh_2d_inla(
  loc.domain = cbind(c(0, 10, 10, 0), c(0, 0, 10, 10)),
  max.edge   = c(1, 3)
)
spde  <- inla.spde2.pcmatern(mesh, prior.range = c(3, 0.5),
                                   prior.sigma  = c(1, 0.01))

# Fit a spatial Gaussian model. inlabru >= 2.12 uses bru_obs() in place
# of the deprecated like().
cmp <- ~ field(coordinates, model = spde) + Intercept(1)
fit <- bru(
  cmp,
  bru_obs(formula = value ~ ., family = "gaussian", data = obs_sp),
  options = bru_options(control.compute = list(config = TRUE))
)

# Wrap and pin. coord_names and crs are required for the /predict endpoint.
# Pass metadata at construction so it is in place before vetiver_api() runs.
v <- vetiver_model(
  fit, "spatial_gaussian",
  metadata = list(
    pred_formula = "~ Intercept + field",
    n_samples    = 500L,
    coord_names  = c("x", "y"),   # column names in obs_sp that hold coordinates
    crs          = 32632           # EPSG code; use NA if data has no CRS
  )
)
board <- board_temp()
vetiver_pin_write(board, v)


## -----------------------------------------------------------------------------
tidy(fit, effects = "fixed")

tidy(fit, effects = "hyperpar")

glance(fit)


## -----------------------------------------------------------------------------
# WRONG for spatial models — this drops the spatial component
bru_reg(family = "gaussian") |>
  set_engine("inlabru") |>
  fit(y ~ field + Intercept(1), data = obs_sp)


## -----------------------------------------------------------------------------
v <- vetiver_model(
  fit,
  "custom_schema",
  save_prototype = tibble::tibble(lon = 0.0, lat = 0.0, x1 = 0.0)
)
v$metadata$user$coord_names <- c("lon", "lat")  # match what you sent above


## -----------------------------------------------------------------------------
v <- vetiver_model(
  fit,
  "multi_lhood_spatial",
  save_prototype = tibble::tibble(x = 0, y = 0)
)

