#' Bayesian Estimation for the Modified Topp-Leone Distribution
#'
#' Estimates the shape parameter \code{alpha} of the Modified Topp-Leone (MTL) distribution
#' under informative (Gamma) and non-informative priors using symmetric (SELF) and asymmetric
#' (ELF, PLF, GELF) loss functions, along with Chen-Shao Highest Posterior Density (HPD) intervals.
#'
#' @param x Vector of sample observations (\code{x > 0}).
#' @param prior Type of prior distribution: \code{"informative"} (Gamma(a, b)) or \code{"noninformative"} (\code{a = 0, b = 0}).
#' @param a Shape parameter for Gamma prior (hyperparameter \code{a > 0}).
#' @param b Rate parameter for Gamma prior (hyperparameter \code{b > 0}).
#' @param loss Loss function: \code{"self"} (Squared Error Loss), \code{"elf"} (Entropy Loss),
#'   \code{"plf"} (Precautionary Loss), \code{"gelf"} (Generalized Entropy Loss), or \code{"all"}.
#' @param delta Constant for Generalized Entropy Loss Function (\code{delta != 0}). Default is 1.
#' @param n.draws Number of MCMC iterations (default: 10000).
#' @param burn.in Number of initial draws to discard as burn-in (default: 1000).
#' @param thin Thinning interval for MCMC chain (default: 1).
#' @param conf.level Credible level for HPD interval estimation (default: 0.95).
#'
#' @return
#' A list containing point estimates under specified loss functions, posterior standard error (PSE),
#' posterior summary statistics, MCMC sample draws, and the 100*(1 - alpha)\% HPD interval.
#'
#' @references
#' Singh, B., Tyagi, S., Singh, R. P., and Tyagi, A. (2025). Modified Topp-Leone
#' Distribution: Properties, Classical and Bayesian Estimation with Application to COVID-19
#' and Reliability Data. \emph{Thailand Statistician}, 23(1), 72-96.
#'
#' Chen, M. H., and Shao, Q. M. (1999). Monte Carlo estimation of Bayesian credible and HPD intervals.
#' \emph{Journal of Computational and Graphical Statistics}, 8(1), 69-92.
#'
#' Calabria, R., and Pulcini, G. (1996). Point estimation under asymmetric loss functions for left-truncated
#' exponential samples. \emph{Communications in Statistics - Theory and Methods}, 25(3), 585-600.
#'
#' @author Shikhar Tyagi, Abhishek Tyagi, Arvind Pandey, Bhupendra Singh, Vrijesh Tripathi
#'
#' @examples
#' set.seed(123)
#' sample_data <- rmtl(n = 30, alpha = 2.5)
#'
#' # Bayesian Estimation under Non-informative Prior
#' bayes_mtl(x = sample_data, prior = "noninformative", loss = "all")
#'
#' # Bayesian Estimation under Informative Prior (a = 2, b = 1)
#' bayes_mtl(x = sample_data, prior = "informative", a = 2, b = 1, loss = "self")
#'
#' @name bayes_mtl
#' @rdname bayes_mtl
#' @export
bayes_mtl <- function(x, prior = c("informative", "noninformative"),
                      a = 1, b = 1, loss = c("self", "elf", "plf", "gelf", "all"),
                      delta = 1, n.draws = 10000, burn.in = 1000, thin = 1,
                      conf.level = 0.95) {
  prior <- match.arg(prior)
  loss <- match.arg(loss)
  
  x <- x[!is.na(x) & x > 0]
  n <- length(x)
  if (n == 0) stop("Vector 'x' must contain positive numeric values.")
  
  if (prior == "noninformative") {
    shape_post <- n
    rate_post <- sum(log(((1 + x)^2) / (x * (2 + x))))
  } else {
    if (a <= 0 || b <= 0) stop("Hyperparameters 'a' and 'b' must be positive for informative prior.")
    shape_post <- n + b
    rate_post <- a + sum(log(((1 + x)^2) / (x * (2 + x))))
  }
  
  # Generate exact posterior draws from Gamma distribution
  raw_draws <- stats::rgamma(n.draws, shape = shape_post, rate = rate_post)
  
  # Burn-in and Thinning
  post_draws <- raw_draws[(burn.in + 1):n.draws]
  if (thin > 1) {
    post_draws <- post_draws[seq(1, length(post_draws), by = thin)]
  }
  
  # Point Estimates under Loss Functions
  hat_self <- mean(post_draws)
  hat_elf <- 1 / mean(1 / post_draws)
  hat_plf <- sqrt(mean(post_draws^2))
  hat_gelf <- (mean(post_draws^(-delta)))^(-1 / delta)
  
  pse <- stats::sd(post_draws)
  
  # Chen-Shao HPD Interval calculation
  sorted_draws <- sort(post_draws)
  m_len <- length(sorted_draws)
  k_len <- floor(conf.level * m_len)
  
  widths <- sorted_draws[(1 + k_len):m_len] - sorted_draws[1:(m_len - k_len)]
  min_idx <- which.min(widths)
  hpd_lower <- sorted_draws[min_idx]
  hpd_upper <- sorted_draws[min_idx + k_len]
  
  loss_estimates <- c(
    SELF = hat_self,
    ELF = hat_elf,
    PLF = hat_plf,
    GELF = hat_gelf
  )
  
  if (loss != "all") {
    sel_name <- toupper(loss)
    point_est <- loss_estimates[sel_name]
  } else {
    point_est <- loss_estimates
  }
  
  res <- list(
    method = paste("Bayesian Estimation under", prior, "prior"),
    prior = prior,
    hyperparams = if (prior == "informative") c(a = a, b = b) else c(a = 0, b = 0),
    estimates = point_est,
    PSE = pse,
    conf.level = conf.level,
    hpd = c(Lower = hpd_lower, Upper = hpd_upper),
    posterior_summary = c(
      Mean = mean(post_draws),
      Median = stats::median(post_draws),
      SD = pse,
      Q2.5 = stats::quantile(post_draws, 0.025),
      Q97.5 = stats::quantile(post_draws, 0.975)
    ),
    draws = post_draws
  )
  class(res) <- "mtl_bayes"
  return(res)
}
