#' Simulate survey microdata and overlapping census margins
#'
#' @param seed Integer random-number seed.
#' @param n Survey sample size.
#' @param areas Character vector of area labels.
#' @return A list with `survey`, `margins`, and the latent `truth` table.
#' @export
simulate_inter_data <- function(seed = 123, n = 500,
                                areas = paste0("A", 1:6)) {
  if (!is.numeric(seed) || length(seed) != 1L || !is.finite(seed)) {
    stop("`seed` must be one finite number.", call. = FALSE)
  }
  if (!is.numeric(n) || length(n) != 1L || n < 50) {
    stop("`n` must be at least 50.", call. = FALSE)
  }
  if (!is.character(areas) || length(areas) < 2L || anyDuplicated(areas)) {
    stop("`areas` must contain at least two distinct labels.", call. = FALSE)
  }
  old_seed <- if (exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE)) {
    get(".Random.seed", envir = .GlobalEnv, inherits = FALSE)
  } else {
    NULL
  }
  on.exit(.inter_restore_rng(old_seed), add = TRUE)
  set.seed(as.integer(seed))

  truth <- expand.grid(
    area = areas,
    sex = c("Female", "Male"),
    age = c("18-34", "35-54", "55+"),
    residence = c("Rural", "Urban"),
    KEEP.OUT.ATTRS = FALSE,
    stringsAsFactors = FALSE
  )
  area_effect <- stats::setNames(seq(-0.45, 0.45, length.out = length(areas)),
                                areas)
  log_size <- 6.0 +
    0.20 * (truth$sex == "Female") +
    0.30 * (truth$residence == "Urban") +
    0.18 * (truth$age == "35-54") -
    0.12 * (truth$age == "55+") +
    area_effect[truth$area]
  truth$population <- pmax(25, round(exp(log_size)))
  linear_predictor <- -1.25 +
    0.35 * (truth$sex == "Female") +
    0.55 * (truth$age == "18-34") -
    0.30 * (truth$age == "55+") +
    0.45 * (truth$residence == "Rural") +
    0.25 * (truth$sex == "Female" & truth$residence == "Rural") +
    area_effect[truth$area]
  truth$probability <- stats::plogis(linear_predictor)

  chosen <- sample.int(nrow(truth), size = as.integer(n), replace = TRUE,
                       prob = truth$population)
  survey <- truth[chosen, c("area", "sex", "age", "residence"), drop = FALSE]
  survey$unemployed <- stats::rbinom(nrow(survey), 1,
                                     truth$probability[chosen])
  sample_counts <- table(chosen)
  survey$weight <- truth$population[chosen] /
    as.numeric(sample_counts[as.character(chosen)])
  survey$strata <- survey$area
  survey$psu <- paste0(survey$area, "-", sample.int(5L, nrow(survey),
                                                    replace = TRUE))
  rownames(survey) <- NULL

  aggregate_margin <- function(variables) {
    out <- stats::aggregate(truth$population, truth[variables], sum,
                            drop = FALSE)
    names(out)[ncol(out)] <- "Freq"
    out
  }
  margins <- list(
    area_sex_age = aggregate_margin(c("area", "sex", "age")),
    area_sex_residence = aggregate_margin(c("area", "sex", "residence")),
    area_age = aggregate_margin(c("area", "age"))
  )
  list(survey = survey, margins = margins, truth = truth)
}

#' Load the reproducible interSAE example
#'
#' @return The same components as [simulate_inter_data()] using fixed settings.
#' @export
inter_example <- function() {
  simulate_inter_data(seed = 2026, n = 480)
}
