#' @title Generalized Non-Central Fuzzy Dynamic Sampling
#' @description Simulates discrete trajectory of fuzzy success accumulation under dynamic state-dependent weights.
#' @param n Integer. Number of draws (sample size).
#' @param Z Matrix. Latent feature matrix (N x d) for finite population universe.
#' @param mu Function or Vector. Fuzzy membership mapping mu(z) in [0, 1].
#' @param w0 Function or Vector. Baseline intrinsic attraction weights w0(z) > 0.
#' @param gamma_kernel Function. Symmetric interaction kernel gamma(z_i, z_j).
#' @param delta Vector or Matrix. Depletion/decay rates delta_i(t).
#' @return List containing selected indices, trajectory of fuzzy mass X_t, and final mass.
#' @export
rfuzzyurn <- function(n, Z, mu, w0, gamma_kernel = NULL, delta = NULL) {
  N <- if (is.matrix(Z)) nrow(Z) else length(Z)
  
  mu_vec <- if (is.function(mu)) apply(Z, 1, mu) else mu
  w0_vec <- if (is.function(w0)) apply(Z, 1, w0) else w0
  
  if (is.null(delta)) delta <- matrix(0, nrow = N, ncol = n)
  if (is.vector(delta)) delta <- matrix(delta, nrow = N, ncol = n, byrow = FALSE)
  
  selected_indices <- integer(n)
  X_t <- numeric(n + 1)
  X_t[1] <- 0
  
  unobserved <- 1:N
  log_interaction <- numeric(N)
  cum_depletion <- rep(1, N)
  
  for (t in 1:n) {
    current_weights <- w0_vec[unobserved] * exp(log_interaction[unobserved]) * cum_depletion[unobserved]
    Omega_t <- sum(current_weights)
    
    if (Omega_t <= 0) stop("Total transition weight sum Omega(t) non-positive.")
    
    p_t <- current_weights / Omega_t
    drawn_rel_idx <- sample.int(length(unobserved), size = 1, prob = p_t)
    drawn_idx <- unobserved[drawn_rel_idx]
    
    selected_indices[t] <- drawn_idx
    X_t[t + 1] <- X_t[t] + mu_vec[drawn_idx]
    
    if (!is.null(gamma_kernel)) {
      for (idx in unobserved) {
        log_interaction[idx] <- log_interaction[idx] + gamma_kernel(Z[idx, ], Z[drawn_idx, ])
      }
    }
    
    cum_depletion <- cum_depletion * (1 - delta[, t])
    unobserved <- setdiff(unobserved, drawn_idx)
  }
  
  return(list(
    selected_units = selected_indices,
    X_trajectory = X_t,
    final_fuzzy_mass = X_t[n + 1]
  ))
}
