#' Random Data Generation under Adaptive Type-I Progressive Hybrid Censoring Scheme
#'
#' Generates random censored lifetimes under the Adaptive Type-I Progressive Hybrid Censoring Scheme
#' as described by Lin and Huang (2012).
#'
#' @param n Integer, total number of units placed on test.
#' @param m Integer, pre-fixed target number of failures (1 <= m <= n).
#' @param T_thresh Numeric, pre-fixed time threshold parameter T > 0.
#' @param R Numeric vector of length m, progressive censoring scheme satisfying sum(R) + m = n.
#' @param pdf Function, user-supplied probability density function pdf(x, par).
#' @param cdf Function, 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 lifetime distribution.
#' @param seed Optional integer, seed for random number generation.
#' @param lower Numeric, lower bound for numerical root finding (default 1e-7).
#' @param upper Numeric, upper bound for numerical root finding (default 1e5).
#'
#' @return A list containing:
#' \item{data}{Numeric vector of observed failure times up to test termination.}
#' \item{censored_at_T}{Logical indicator or count of units censored at time T.}
#' \item{T_thresh}{The time threshold T.}
#' \item{n}{Total sample size.}
#' \item{m}{Target number of failures.}
#' \item{R_effective}{Effective progressive censoring plan applied.}
#' \item{d}{Total number of failures observed.}
#' \item{scheme}{String descriptor of the censoring scheme.}
#'
#' @references
#' Lin, C. T., & Huang, Y. L. (2012). On adaptive Type-I progressive hybrid censored samples.
#' \emph{Journal of Statistical Computation and Simulation}, 82(7), 1005-1018.
#'
#' Balakrishnan, N., Cramer, E., & Kundu, D. (2023). \emph{Hybrid censoring know-how: Designs and implementations}. Academic Press.
#'
#' @export
#' @examples
#' # Example: Standard Exponential distribution
#' set.seed(123)
#' my_cdf <- function(x, par) pexp(x, rate = par[1])
#' my_pdf <- function(x, par) dexp(x, rate = par[1])
#' my_qdf <- function(p, par) qexp(p, rate = par[1])
#' R_plan <- c(rep(1, 8), rep(0, 4))
#' res <- r_adapt1_phcs(
#'   n = 20, m = 12, T_thresh = 2.5,
#'   R = R_plan, pdf = my_pdf,
#'   cdf = my_cdf, qdf = my_qdf, par = 0.5
#' )
#' print(res$data)
r_adapt1_phcs <- function(n, m, T_thresh, R, pdf = NULL, cdf = NULL, qdf = NULL, par = NULL, seed = NULL, lower = 1e-7, upper = 1e5) {
  if (!is.null(seed)) set.seed(seed)
  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(cdf) && is.null(qdf)) stop("Either cdf or qdf must be provided.")
  if (is.null(par)) stop("Parameter vector 'par' must be provided.")
  
  gamma_vec <- numeric(n)
  R_full <- c(R, rep(0, n - m))
  for (i in seq_len(n)) {
    gamma_vec[i] <- sum(R_full[i:n]) + (n - i + 1)
  }
  
  U <- stats::runif(n)
  V <- numeric(n)
  W_1 <- U[1]^(1 / gamma_vec[1])
  V[1] <- 1 - W_1
  
  if (n > 1) {
    for (i in 2:n) {
      W_i <- U[i]^(1 / gamma_vec[i])
      V[i] <- 1 - (1 - V[i - 1]) * W_i
    }
  }
  
  X_all <- numeric(n)
  if (!is.null(qdf)) {
    X_all <- qdf(V, par)
  } else {
    for (i in seq_len(n)) {
      X_all[i] <- .solve_quantile(cdf, V[i], par, lower_bound = lower, upper_bound = upper)
    }
  }
  X_all <- sort(X_all)
  
  obs_failures <- X_all[X_all <= T_thresh]
  d <- length(obs_failures)
  
  if (d >= m) {
    R_eff <- c(R[1:(m - 1)], rep(0, d - m + 1))
    cens_T <- n - d - sum(R[1:(m - 1)])
  } else {
    R_eff <- R[1:d]
    cens_T <- n - d - sum(R_eff)
  }
  
  return(list(
    data = obs_failures,
    censored_at_T = max(0, cens_T),
    T_thresh = T_thresh,
    n = n,
    m = m,
    R_effective = R_eff,
    d = d,
    scheme = "Adaptive Type-I PHCS"
  ))
}

#' Random Data Generation under Adaptive Type-II Progressive Hybrid Censoring Scheme
#'
#' Generates random censored lifetimes under the Adaptive Type-II Progressive Hybrid Censoring Scheme
#' as described by Ng, Kundu, and Chan (2009).
#'
#' @param n Integer, total number of units placed on test.
#' @param m Integer, pre-fixed target number of failures (1 <= m <= n).
#' @param T_thresh Numeric, pre-fixed time threshold parameter T > 0.
#' @param R Numeric vector of length m, progressive censoring scheme satisfying sum(R) + m = n.
#' @param pdf Function, user-supplied probability density function pdf(x, par).
#' @param cdf Function, 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 lifetime distribution.
#' @param seed Optional integer, seed for random number generation.
#' @param lower Numeric, lower bound for numerical root finding (default 1e-7).
#' @param upper Numeric, upper bound for numerical root finding (default 1e5).
#'
#' @return A list containing:
#' \item{data}{Numeric vector of m observed failure times.}
#' \item{T_thresh}{The time threshold T.}
#' \item{n}{Total sample size.}
#' \item{m}{Target number of failures.}
#' \item{R_effective}{Effective progressive censoring plan applied.}
#' \item{d}{Number of failures observed at or before time T.}
#' \item{scheme}{String descriptor of the censoring scheme.}
#'
#' @references
#' Ng, H. K. T., Kundu, D., & Chan, P. S. (2009). Statistical inference for a progressive line-testing experiment with adaptive progressive Type-II censoring.
#' \emph{IEEE Transactions on Reliability}, 58(4), 634-642.
#'
#' Balakrishnan, N., Cramer, E., & Kundu, D. (2023). \emph{Hybrid censoring know-how: Designs and implementations}. Academic Press.
#'
#' @export
#' @examples
#' # Example: Standard Exponential distribution
#' set.seed(123)
#' my_cdf <- function(x, par) pexp(x, rate = par[1])
#' my_pdf <- function(x, par) dexp(x, rate = par[1])
#' my_qdf <- function(p, par) qexp(p, rate = par[1])
#' R_plan <- c(rep(1, 8), rep(0, 4))
#' res <- r_adapt2_phcs(
#'   n = 20, m = 12, T_thresh = 2.5,
#'   R = R_plan, pdf = my_pdf,
#'   cdf = my_cdf, qdf = my_qdf, par = 0.5
#' )
#' print(res$data)
r_adapt2_phcs <- function(n, m, T_thresh, R, pdf = NULL, cdf = NULL, qdf = NULL, par = NULL, seed = NULL, lower = 1e-7, upper = 1e5) {
  if (!is.null(seed)) set.seed(seed)
  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(cdf) && is.null(qdf)) stop("Either cdf or qdf must be provided.")
  if (is.null(par)) stop("Parameter vector 'par' must be provided.")
  
  gamma_vec <- numeric(m)
  for (i in seq_len(m)) {
    gamma_vec[i] <- sum(R[i:m]) + (m - i + 1)
  }
  
  U <- stats::runif(m)
  V <- numeric(m)
  W_1 <- U[1]^(1 / gamma_vec[1])
  V[1] <- 1 - W_1
  
  if (m > 1) {
    for (i in 2:m) {
      W_i <- U[i]^(1 / gamma_vec[i])
      V[i] <- 1 - (1 - V[i - 1]) * W_i
    }
  }
  
  X_init <- numeric(m)
  if (!is.null(qdf)) {
    X_init <- qdf(V, par)
  } else {
    for (i in seq_len(m)) {
      X_init[i] <- .solve_quantile(cdf, V[i], par, lower_bound = lower, upper_bound = upper)
    }
  }
  X_init <- sort(X_init)
  
  J <- sum(X_init <= T_thresh)
  
  if (J >= m - 1) {
    R_eff <- R
    X_obs <- X_init
  } else {
    R_eff <- c(if(J > 0) R[1:J] else numeric(0), rep(0, m - J - 1), n - m - sum(if(J > 0) R[1:J] else 0))
    X_obs <- X_init
  }
  
  return(list(
    data = X_obs,
    T_thresh = T_thresh,
    n = n,
    m = m,
    R_effective = R_eff,
    d = J,
    scheme = "Adaptive Type-II PHCS"
  ))
}
