#' Data Generation under Improved Adaptive Type-II Progressive Censoring Scheme
#'
#' Generates random censored lifetime data under the Improved Adaptive Type-II Progressive Censoring Scheme (IAT-II PCS)
#' as described by Dev and Chacko (2026) and Yan et al. (2021).
#'
#' @param n Integer, total number of units placed on test (n >= 1).
#' @param m Integer, pre-fixed target number of failures (1 <= m <= n).
#' @param T1 Numeric, first pre-fixed threshold time point (T1 > 0).
#' @param T2 Numeric or NULL, second pre-fixed threshold time point (T2 > T1). If NULL, defaults to Inf (standard AT-II PCS).
#' @param R Numeric vector of length m, pre-fixed progressive censoring scheme satisfying sum(R) + m = n.
#' @param pdf Function (optional), user-supplied probability density function pdf(x, par).
#' @param cdf Function (optional), user-supplied cumulative distribution function cdf(x, par).
#' @param qdf Function (optional), user-supplied quantile function qdf(p, par).
#' @param par Numeric vector, true parameter values for the specified distribution.
#' @param seed Optional integer, seed for random number generation.
#' @param lower Numeric, lower bound for numerical quantile root finding (default 1e-7).
#' @param upper Numeric, upper bound for numerical quantile root finding (default 1e5).
#'
#' @return An object of class \code{"impadapt2_sample"} containing:
#' \item{data}{Numeric vector of observed failure times up to test termination.}
#' \item{case}{Character string indicating the realized censoring case ("Case I", "Case II", or "Case III").}
#' \item{d1}{Number of failures observed at or before threshold time T1.}
#' \item{d2}{Number of failures observed at or before threshold time T2.}
#' \item{D1}{Value of D1 parameter for likelihood construction.}
#' \item{D2}{Value of D2 parameter (total observed failures) for likelihood construction.}
#' \item{R_effective}{Numeric vector of effective progressive censoring plan applied.}
#' \item{R_star}{Number of remaining live units removed at experiment termination time T_star.}
#' \item{T_star}{Terminal time of the experiment (X_m for Cases I and II; T2 for Case III).}
#' \item{T1}{Threshold time T1.}
#' \item{T2}{Threshold time T2.}
#' \item{n}{Total sample size.}
#' \item{m}{Target failure count.}
#' \item{R_initial}{Initial pre-fixed progressive censoring plan.}
#' \item{par}{True parameter values.}
#'
#' @references
#' Dev, S. S., & Chacko, M. (2026). Statistical inference for generalized exponential distribution under improved adaptive Type-II progressive censoring.
#' \emph{Journal of the Iranian Statistical Society}, 25(2), 1-29. \doi{10.22034/jirss.2026.2077492.1165}.
#'
#' Yan, L., Zhang, Q., & Dong, A. (2021). Inference for the Burr XII distribution based on improved adaptive progressive Type-II censoring.
#' \emph{Journal of Computational and Applied Mathematics}, 381, 113022. \doi{10.1016/j.cam.2020.113022}.
#'
#' Balakrishnan, N., & Sandhu, R. (1995). A simple simulational algorithm for generating progressively Type-II censored samples.
#' \emph{The American Statistician}, 49(2), 229-230.
#'
#' @export
#' @examples
#' set.seed(123)
#' # Data generation for Generalized Exponential distribution
#' ge_cdf <- function(x, par) (1 - exp(-par[2] * x))^par[1]
#' ge_pdf <- function(x, par) par[1] * par[2] * exp(-par[2] * x) * (1 - exp(-par[2] * x))^(par[1] - 1)
#' ge_qdf <- function(p, par) - (1 / par[2]) * log(1 - p^(1 / par[1]))
#'
#' res <- r_impadapt2_censor(
#'   n = 20, m = 10, T1 = 0.8, T2 = 2.0,
#'   R = c(rep(1, 10)),
#'   pdf = ge_pdf, cdf = ge_cdf, qdf = ge_qdf,
#'   par = c(1.5, 0.8)
#' )
#' print(res)
r_impadapt2_censor <- function(n, m, T1, T2 = NULL, R, pdf = NULL, cdf = NULL, qdf = NULL, par = NULL, seed = NULL, lower = 1e-7, upper = 1e5) {
  if (!is.null(seed)) set.seed(seed)
  
  if (m < 1 || m > n) stop("'m' must satisfy 1 <= m <= n.")
  if (T1 <= 0) stop("'T1' must be positive.")
  if (is.null(T2)) {
    T2 <- Inf
  } else if (T2 <= T1) {
    stop("'T2' must be greater than 'T1'.")
  }
  if (length(R) != m) stop("Length of progressive scheme 'R' must equal 'm'.")
  if (sum(R) + m != n) stop("Sum of progressive scheme 'R' and 'm' must equal 'n'.")
  if (is.null(par)) stop("Parameter vector 'par' must be provided.")
  
  # Default to Generalized Exponential if pdf/cdf/qdf are all NULL
  if (is.null(pdf) && is.null(cdf) && is.null(qdf)) {
    pdf <- .ge_pdf
    cdf <- .ge_cdf
    qdf <- .ge_qdf
  } else if (is.null(cdf) && is.null(qdf)) {
    stop("Either 'cdf' or 'qdf' must be provided.")
  }
  
  # Step 1: Generate standard Progressive Type-II Censored sample U(0,1)
  gamma_vec <- numeric(m)
  for (i in seq_len(m)) {
    gamma_vec[i] <- (m - i + 1) + sum(R[i:m])
  }
  
  W <- stats::runif(m)
  V <- numeric(m)
  V[1] <- W[1]^(1 / gamma_vec[1])
  if (m > 1) {
    for (i in 2:m) {
      V[i] <- W[i]^(1 / gamma_vec[i])
    }
  }
  
  U <- numeric(m)
  cum_prod <- 1
  for (i in seq_len(m)) {
    cum_prod <- cum_prod * V[m - i + 1]
    U[i] <- 1 - cum_prod
  }
  U <- sort(U)
  
  # Transform U to target distribution quantile X
  X_full <- numeric(m)
  if (!is.null(qdf)) {
    X_full <- qdf(U, par)
  } else {
    for (i in seq_len(m)) {
      X_full[i] <- .solve_quantile(cdf, U[i], par, lower_bound = lower, upper_bound = upper)
    }
  }
  X_full <- sort(X_full)
  
  # Step 2: Determine case realized under IAT-II PCS
  d1 <- sum(X_full <= T1)
  
  if (X_full[m] < T1) {
    case_type <- "Case I"
    X_obs <- X_full
    d2 <- m
    D1 <- m
    D2 <- m
    R_eff <- R
    R_star <- R[m]
    T_star <- X_full[m]
  } else if (X_full[m] < T2) {
    case_type <- "Case II"
    X_obs <- X_full
    d2 <- sum(X_full <= T2)
    D1 <- d1
    D2 <- m
    zero_pad <- if (m - d1 - 1 > 0) rep(0, m - d1 - 1) else numeric(0)
    R_eff <- c(if (d1 > 0) R[seq_len(d1)] else numeric(0), zero_pad, n - m - sum(if (d1 > 0) R[seq_len(d1)] else 0))
    R_star <- n - m - sum(if (d1 > 0) R[seq_len(d1)] else 0)
    T_star <- X_full[m]
  } else {
    case_type <- "Case III"
    d2 <- sum(X_full <= T2)
    X_obs <- X_full[seq_len(d2)]
    D1 <- d1
    D2 <- d2
    zero_pad <- if (d2 - d1 - 1 > 0) rep(0, d2 - d1 - 1) else numeric(0)
    R_eff <- c(if (d1 > 0) R[seq_len(d1)] else numeric(0), zero_pad, n - d2 - sum(if (d1 > 0) R[seq_len(d1)] else 0))
    R_star <- n - d2 - sum(if (d1 > 0) R[seq_len(d1)] else 0)
    T_star <- T2
  }
  
  res <- list(
    data = X_obs,
    case = case_type,
    d1 = d1,
    d2 = d2,
    D1 = D1,
    D2 = D2,
    R_effective = R_eff,
    R_star = R_star,
    T_star = T_star,
    T1 = T1,
    T2 = T2,
    n = n,
    m = m,
    R_initial = R,
    par = par
  )
  class(res) <- "impadapt2_sample"
  return(res)
}

#' @export
print.impadapt2_sample <- function(x, ...) {
  cat("Improved Adaptive Type-II Progressive Censored Sample (IAT-II PCS)\n")
  cat("---------------------------------------------------------------\n")
  cat("Realized Scenario :", x$case, "\n")
  cat("Total Units (n)   :", x$n, "\n")
  cat("Target Failures(m):", x$m, "\n")
  cat("Failures <= T1    :", x$d1, "(T1 =", x$T1, ")\n")
  cat("Failures <= T2    :", x$d2, "(T2 =", if(is.infinite(x$T2)) "Inf" else x$T2, ")\n")
  cat("Observed Count    :", length(x$data), "\n")
  cat("Terminal Time T*  :", round(x$T_star, 4), "\n")
  cat("Observed Failure Times:\n")
  print(round(x$data, 4))
  cat("\nEffective Progressive Censoring Scheme R_eff:\n")
  print(x$R_effective)
  cat("Remaining Units Removed at T* (R*):", x$R_star, "\n")
  invisible(x)
}
