#' fit Bayesian penalized quantile regression for a sparse linear model, binary LASSO, group LASSO, or varying coefficient model based on spike-and-slab priors and/or the horseshoe family of priors
#' 
#' @keywords models
#' @param g the matrix of predictors (subject to selection). Users do not need to specify an intercept which will be automatically included. 
#' @param y the response variable.
#' @param u a vector of effect modifying variable of the quantile varying coefficient model. When fitting a linear model or group LASSO, u = NULL. The default value is NULL.
#' @param e a matrix of clinical covariates not subject to selection. The default value is NULL.
#' @param quant the quantile level specified by users. Required when robust = TRUE. Ignored (set to NULL) when robust = FALSE.The default value is 0.5.
#' @param d a positive integer denotes the group size. When fitting a sparse linear or varying coefficient model, d = NULL. The default value is NULL.
#' @param iterations the number of MCMC iterations. The default value is 10,000.
#' @param burn.in the number of burn-in iterations. If NULL, the first half of MCMC iterations will be discarded as burn-ins.
#' @param robust logical flag. If TRUE, robust methods are used. Otherwise, non-robust methods are used. The default value is TRUE.
#' @param prior the type of prior used for variable selection. Users can specify "SS" for the spike-and-slab prior, "HS" for the horseshoe prior, "HS+" for the horseshoe plus prior, "RHS" for the regularized horseshoe prior and "Laplace" for the Laplace prior. The default value is "SS".
#' @param model the model to be fitted. Users can specify "linear" for a sparse linear model (with a continuous response), "binary" for binary LASSO, "group" for group LASSO and "VC" for a varying coefficient model.
#' @param hyper a named list of hyper-parameters. The default value is NULL.
#' @param debugging logical flag. If TRUE, progress will be output to the console and extra information will be returned. The default value is FALSE.
#'
#' @details 
#' The sparse linear quantile regression model described in "\code{\link{data}}" is:
#' \deqn{Y_{i}=\sum_{k=1}^{q} E_{ik} \beta_k +\sum_{j=0}^{p}X_{ij}\gamma_j +\epsilon_{i},}
#' where \eqn{\beta_k}'s are the regression coefficients for clinical covariates and \eqn{\gamma_j}'s are the regression coefficients of \eqn{\boldsymbol X}.
#' 
#' The binary quantile regression model described in "\code{\link{data}}" is:
#' \deqn{\tilde{Y}_{i}=\sum_{k=1}^{q} E_{ik} \beta_k +\sum_{j=0}^{p}X_{ij}\gamma_j +\epsilon_{i},}
#' where \eqn{\beta_k}'s are the regression coefficients for clinical covariates and \eqn{\gamma_j}'s are the regression coefficients of \eqn{\boldsymbol X}.
#' 
#' \eqn{Y_{i}=1} if \eqn{\tilde{Y}_{i}>0} and \eqn{Y_{i}=0} otherwise.
#' 
#' The group LASSO model described in "\code{\link{data}}" is:
#' \deqn{Y_{i}=\sum_{k=1}^{q} E_{ik} \beta_k + X_{i0}\gamma_0+ \sum_{j=1}^{m}\boldsymbol{X_{ij}^\top}\boldsymbol{\gamma_j} +\epsilon_{i},}
#' where \eqn{\beta_k}'s are the regression coefficients for clinical covariates and \eqn{\boldsymbol{\gamma_j} = (\gamma_{j1},\dots,\gamma_{jd})^\top} is the vector of regression coefficients of the \eqn{n \times d} matrix \eqn{\boldsymbol X_{j}}.
#' 
#' The quantile varying coefficient model described in "\code{\link{data}}" is:
#' \deqn{Y_{i}=\sum_{k=1}^{q} E_{ik} \beta_k +\sum_{j=0}^{p}\gamma_j(V_i)X_{ij} +\epsilon_{i},}
#' where \eqn{\beta_k}'s are the regression coefficients for the clinical covariates, and \eqn{\gamma_j}'s are the varying intercept and varying coefficients for predictors (e.g. genetic factors), respectively.
#'
#' 
#' Users can modify the hyper-parameters by providing a named list of hyper-parameters via the argument `hyper'.
#' The list can have the following named components
#' \describe{
#'   \item{a0, b0: }{ shape parameters of the Beta priors (\eqn{\pi^{a_{0}-1}(1-\pi)^{b_{0}-1}}) on \eqn{\pi_{0}}.}
#'   \item{c1, c2: }{ the shape parameter and the rate parameter of the Gamma prior on \eqn{\nu}.}
#' }
#' 
#' Please check the references for more details about the prior distributions.
#' 
#' @return an object of class "pqrBayes" is returned, which is a list with components:
#' \item{obj}{a list of posterior samples from the MCMC and other parameters}
#' \item{coefficients}{a list of posterior estimates of coefficients}
#' 
#' @examples
#' ## The Bayesian regularized quantile regression under linear and binary model
#' data(data)
#' data = data$data_linear
#' g=data$g
#' y=data$y
#' e=data$e
#' data(data)
#' data_1=data$data_binary
#' g_1=data_1$g
#' y_1=data_1$y
#' e_1=data_1$e
#' 
#' fit1=pqrBayes(g,y,e,model="linear")
#' fit1_1=pqrBayes(g_1,y_1,e_1,model="binary")

#' \donttest{
#'
#' ## Non-sparse robust example (Bayesian Quantile LASSO)
#' fit2 <- pqrBayes(g, y, e, prior = "Laplace", model = "linear")
#'
#' ## Non-robust example (Bayesian LASSO)
#' fit3 <- pqrBayes(g, y, e, quant = NULL, robust = FALSE, model = "linear")
#' }

#' 
#' ## The Bayesian quantile group LASSO model
#' data(data)
#' data = data$data_group
#' g=data$g
#' y=data$y
#' e=data$e
#' 
#' fit1=pqrBayes(g,y,e,d=3,model="group")
#' \donttest{
#'
#' ## Non-sparse robust Bayesian version
#' fit2 <- pqrBayes(g, y, e, d = 3, prior = "Laplace", model = "group")
#'
#' ## Non-robust Bayesian version
#' fit3 <- pqrBayes(g, y, e, d = 3, quant = NULL, robust = FALSE, model = "group")
#' }

#' ## The regularized Bayesian quantile varying coefficient model
#' data(data)
#' data = data$data_varying
#' g=data$g
#' y=data$y
#' e=data$e
#' u=data$u
#' fit1=pqrBayes(g,y,u,e,model="VC")
#'
#' \donttest{
#'
#' ## Non-sparse robust Bayesian example
#' fit2 <- pqrBayes(g, y, u, e, prior = "Laplace", model = "VC")
#'
#' ## Non-robust Bayesian example
#' fit3 <- pqrBayes(g, y, u, e, quant = NULL,robust = FALSE, model = "VC")
#' }

#' @export
#' @references
#' 
#' Fan, K., Subedi, S., Yang, G., Lu, X., Ren, J. and Wu, C. (2024). Is Seeing Believing? A Practitioner's Perspective on High-dimensional Statistical Inference in Cancer Genomics Studies. {\emph{Entropy}, 26(9).794} \doi{10.3390/e26090794}
#' 
#' Zhou, F., Ren, J., Ma, S. and Wu, C. (2023). The Bayesian regularized quantile varying coefficient model.
#'  {\emph{Computational Statistics & Data Analysis}, 187, 107808} \doi{10.1016/j.csda.2023.107808}
#'  
#' Ren, J., Zhou, F., Li, X., Ma, S., Jiang, Y. and Wu, C. (2023). Robust Bayesian variable selection for gene-environment interactions. 
#' {\emph{Biometrics}, 79(2), 684-694} \doi{10.1111/biom.13670}
#' 
#' Fan, K. and Wu, C. (2025). A New Robust Binary Bayesian LASSO. 
#' {\emph{Stat}, 14 (3), e70078} \doi{10.1002/sta4.70078}
#' 
#' Fan, K., Srijana, S., Dissanayake, V. and Wu, C. (2026). Robust Bayesian high-dimensional variable selection and inference with the horseshoe family of priors. 
#' {\emph{Computational Statistics & Data Analysis}, 219, 108358} \doi{10.1016/j.csda.2026.108358}
#'
#' Ren, J., Zhou, F., Li, X., Chen, Q., Zhang, H., Ma, S., Jiang, Y. and Wu, C. (2020) Semi-parametric Bayesian variable selection for gene-environment interactions.
#' {\emph{Statistics in Medicine}, 39: 617– 638} \doi{10.1002/sim.8434}




pqrBayes <- function(g, y, u=NULL, e=NULL, d = NULL, quant = 0.5, iterations = 10000, 
                     burn.in = NULL, robust = TRUE, prior = "SS", 
                     model,
                     hyper = NULL, debugging = FALSE) {
  
  if (prior %in% c("HS", "HS+", "RHS") && model != "linear") {
    stop("Priors 'HS', 'HS+' and 'RHS' are currently supported only when model = 'linear'.")
  }
  if (!prior %in% c("SS", "HS", "HS+", "RHS", "Laplace")) {
    stop("prior should be one of: 'SS', 'HS', 'HS+', 'RHS' or 'Laplace'.")
  }
  # quant check
  if (robust) {
    if (is.null(quant)) {
      stop("quant must be specified when robust = TRUE.")
    }
  } else {
    if (!is.null(quant)) {
      stop("quant must be NULL when robust = FALSE.")
    }
  }
  
  if (model != "VC" && !is.null(u)) {
    
    stop("Argument 'u' should be NULL unless model = 'VC'.")
    
  }
  
  if (model == "VC" && is.null(u)) {
    
    stop("Argument 'u' must be provided when model = 'VC'.")
    
  }
  
  
  if (model != "group" && !is.null(d)) {
    
    stop("Argument 'd' should be NULL unless model = 'group'.")
    
  }
  
  if (model == "group" && is.null(d)) {
    
    stop("Argument 'd' must be provided when model = 'group'.")
    
  }
  
  if (model == "VC") {
    
    fit = pqrBayes_vc(g, y, u, e, quant, iterations, burn.in, robust, prior, hyper, debugging)
    
  } else if (model == "linear") {
    fit = pqrBayes_lin(g, y, e, quant, iterations, burn.in, robust, prior, hyper, debugging)
    
  } else if (model == "binary") {
    fit = pqrBayes_bin(g, y, e, quant, iterations, burn.in, robust, prior, hyper, debugging)
    
  }else if (model == "group") {
    fit = pqrBayes_g(g, y, e, d, quant, iterations, burn.in, robust, prior, hyper, debugging)
    
  } else {
    stop("model should be one of: 'VC', 'linear', 'binary' or 'group'.")
  }
  
  return(fit)
}

