#' Simulate Step-Stress Accelerated Degradation Data
#'
#' Generates simulated degradation path data for N test units subject to a K-steps step-stress
#' accelerated degradation test (SSADT) under Wiener or Gamma stochastic process models.
#'
#' @param n_units Number of test units (e.g. 5).
#' @param times Vector of inspection time points (e.g. \code{seq(72, 2160, by = 72)}).
#' @param stress_levels Vector of stress levels S = (S1, S2, ..., SK).
#' @param thresholds Vector of degradation thresholds (omega_1, ..., omega_K-1) at which stress is elevated.
#' @param process Character string specifying \code{"wiener"} or \code{"gamma"}.
#' @param model Acceleration model: \code{"arrhenius"} or \code{"power"}.
#' @param params Model parameters: \code{c(a, b, sigma)} for Wiener, or \code{c(a, b, u)} for Gamma.
#'
#' @return A data frame with columns \code{time}, \code{unit1}, \code{unit2}, ..., \code{unitN}.
#'
#' @references
#' Pan, Z., & Balakrishnan, N. (2010). Multiple-Steps Step-Stress Accelerated Degradation Modeling Based on Wiener and Gamma Processes.
#' \emph{Communications in Statistics - Simulation and Computation}, 39(7), 1384-1402. \doi{10.1080/03610918.2010.496060}
#'
#' @export
#' @examples
#' set.seed(42)
#' sim_data <- ssad_simulate(
#'   n_units = 5,
#'   times = seq(72, 2160, by = 72),
#'   stress_levels = c(45, 65, 85),
#'   thresholds = c(90, 160),
#'   process = "wiener",
#'   model = "arrhenius",
#'   params = c(a = 5.3669, b = -2546.7, sigma = 0.1)
#' )
#' head(sim_data)
ssad_simulate <- function(n_units = 5, times = seq(72, 2160, by = 72),
                          stress_levels = c(45, 65, 85), thresholds = c(90, 160),
                          process = c("wiener", "gamma"), model = c("arrhenius", "power"),
                          params) {
  process <- match.arg(process)
  if (is.character(model)) {
    model <- match.arg(model)
  }
  
  eval_acc <- function(S, m_type, par) {
    if (is.function(m_type)) {
      return(m_type(S, par))
    }
    a <- par[1]
    b <- par[2]
    if (m_type == "arrhenius") {
      return(exp(a + b / (273 + S)))
    } else if (m_type == "power") {
      return(a * (S^b))
    } else {
      stop("Unsupported acceleration model.")
    }
  }
  
  K <- length(stress_levels)
  if (length(thresholds) != K - 1) {
    stop("Length of thresholds must be length(stress_levels) - 1.")
  }
  
  M <- length(times)
  dt_vec <- c(times[1], diff(times))
  
  res_mat <- matrix(0, nrow = M, ncol = n_units)
  
  for (i in seq_len(n_units)) {
    x_curr <- 0
    t_curr <- 0
    k_curr <- 1
    
    for (j in seq_len(M)) {
      dt <- dt_vec[j]
      
      # Check current stress level based on x_curr
      while (k_curr < K && x_curr >= thresholds[k_curr]) {
        k_curr <- k_curr + 1
      }
      
      rate_val <- eval_acc(stress_levels[k_curr], model, params[1:2])
      
      if (process == "wiener") {
        sigma <- params[3]
        dx <- stats::rnorm(1, mean = rate_val * dt, sd = sigma * sqrt(dt))
      } else { # gamma
        u <- params[3]
        shape_val <- rate_val * dt
        dx <- stats::rgamma(1, shape = shape_val, rate = u)
      }
      
      x_curr <- x_curr + dx
      res_mat[j, i] <- x_curr
    }
  }
  
  df_res <- data.frame(time = times, res_mat)
  colnames(df_res) <- c("time", paste0("unit", seq_len(n_units)))
  return(df_res)
}
