#' The Modified Topp-Leone Distribution
#'
#' Density, distribution function, quantile function, random generation,
#' survival function, and hazard rate function for the Modified Topp-Leone (MTL)
#' distribution with shape parameter \code{alpha}.
#'
#' @param x,q Vector of quantiles.
#' @param p Vector of probabilities.
#' @param n Number of observations. If \code{length(n) > 1}, the length is taken to be the number required.
#' @param alpha Shape parameter of the MTL distribution (\code{alpha > 0}).
#' @param log,log.p Logical; if \code{TRUE}, probabilities/densities \eqn{p} are given as \eqn{\log(p)}. Default is \code{FALSE}.
#' @param lower.tail Logical; if \code{TRUE} (default), probabilities are \eqn{P[X \le x]}, otherwise \eqn{P[X > x]}.
#'
#' @details
#' The probability density function (PDF) of the Modified Topp-Leone distribution is given by:
#' \deqn{f(x; \alpha) = 2 \alpha (1 + x)^{-(2\alpha + 1)} (2x + x^2)^{\alpha - 1}, \quad x > 0, \; \alpha > 0}
#' The cumulative distribution function (CDF) is given by:
#' \deqn{F(x; \alpha) = \left( \frac{2x + x^2}{(1 + x)^2} \right)^\alpha = \left( 1 - \frac{1}{(1 + x)^2} \right)^\alpha, \quad x > 0, \; \alpha > 0}
#' The quantile function is derived by inverting the CDF:
#' \deqn{Q(p; \alpha) = (1 - p^{1/\alpha})^{-1/2} - 1, \quad 0 < p < 1}
#'
#' @return
#' \code{dmtl} gives the density, \code{pmtl} gives the distribution function,
#' \code{qmtl} gives the quantile function, \code{rmtl} generates random deviates,
#' \code{smtl} gives the survival function, and \code{hmtl} gives the hazard rate function.
#'
#' @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.
#'
#' @author Shikhar Tyagi, Abhishek Tyagi, Arvind Pandey, Bhupendra Singh, Vrijesh Tripathi
#'
#' @examples
#' # Evaluate PDF and CDF at x = 1 with alpha = 1.5
#' dmtl(x = 1, alpha = 1.5)
#' pmtl(q = 1, alpha = 1.5)
#'
#' # Quantile function and random generation
#' p_seq <- c(0.25, 0.50, 0.75)
#' qmtl(p = p_seq, alpha = 1.5)
#' set.seed(123)
#' x_sample <- rmtl(n = 10, alpha = 1.5)
#' x_sample
#'
#' # Survival and Hazard functions
#' smtl(x = 1, alpha = 1.5)
#' hmtl(x = 1, alpha = 1.5)
#'
#' @name ModToppLeone
#' @rdname ModToppLeone
#' @export
dmtl <- function(x, alpha, log = FALSE) {
  if (missing(alpha) || any(alpha <= 0)) {
    stop("Parameter 'alpha' must be positive.")
  }
  
  pdf_val <- numeric(length(x))
  
  valid_idx <- !is.na(x) & x > 0
  if (any(valid_idx)) {
    xv <- x[valid_idx]
    
    log_pdf <- log(2) + log(alpha) + (alpha - 1) * log(xv * (2 + xv)) - (2 * alpha + 1) * log(1 + xv)
    if (log) {
      pdf_val[valid_idx] <- log_pdf
    } else {
      pdf_val[valid_idx] <- exp(log_pdf)
    }
  }
  
  invalid_idx <- !is.na(x) & x <= 0
  if (any(invalid_idx)) {
    pdf_val[invalid_idx] <- if (log) -Inf else 0
  }
  
  pdf_val[is.na(x)] <- NA
  return(pdf_val)
}

#' @rdname ModToppLeone
#' @export
pmtl <- function(q, alpha, lower.tail = TRUE, log.p = FALSE) {
  if (missing(alpha) || any(alpha <= 0)) {
    stop("Parameter 'alpha' must be positive.")
  }
  
  cdf_val <- numeric(length(q))
  
  valid_idx <- !is.na(q) & q > 0
  if (any(valid_idx)) {
    qv <- q[valid_idx]
    
    base_val <- 1 - (1 + qv)^(-2)
    base_val <- pmax(pmin(base_val, 1), 0)
    
    if (lower.tail) {
      if (log.p) {
        cdf_val[valid_idx] <- alpha * log(base_val)
      } else {
        cdf_val[valid_idx] <- base_val^alpha
      }
    } else {
      surv <- 1 - base_val^alpha
      surv <- pmax(pmin(surv, 1), 0)
      if (log.p) {
        cdf_val[valid_idx] <- log(surv)
      } else {
        cdf_val[valid_idx] <- surv
      }
    }
  }
  
  invalid_idx <- !is.na(q) & q <= 0
  if (any(invalid_idx)) {
    if (lower.tail) {
      cdf_val[invalid_idx] <- if (log.p) -Inf else 0
    } else {
      cdf_val[invalid_idx] <- if (log.p) 0 else 1
    }
  }
  
  cdf_val[is.na(q)] <- NA
  return(cdf_val)
}

#' @rdname ModToppLeone
#' @export
qmtl <- function(p, alpha, lower.tail = TRUE, log.p = FALSE) {
  if (missing(alpha) || any(alpha <= 0)) {
    stop("Parameter 'alpha' must be positive.")
  }
  
  if (log.p) {
    p <- exp(p)
  }
  if (!lower.tail) {
    p <- 1 - p
  }
  
  q_val <- numeric(length(p))
  
  out_of_bounds <- !is.na(p) & (p < 0 | p > 1)
  if (any(out_of_bounds)) {
    warning("Probabilities outside [0, 1] produced NaNs.")
    q_val[out_of_bounds] <- NaN
  }
  
  valid_idx <- !is.na(p) & p > 0 & p < 1
  if (any(valid_idx)) {
    pv <- p[valid_idx]
    q_val[valid_idx] <- (1 - pv^(1 / alpha))^(-0.5) - 1
  }
  
  zero_idx <- !is.na(p) & p == 0
  if (any(zero_idx)) {
    q_val[zero_idx] <- 0
  }
  
  one_idx <- !is.na(p) & p == 1
  if (any(one_idx)) {
    q_val[one_idx] <- Inf
  }
  
  q_val[is.na(p)] <- NA
  return(q_val)
}

#' @rdname ModToppLeone
#' @export
rmtl <- function(n, alpha) {
  if (missing(alpha) || any(alpha <= 0)) {
    stop("Parameter 'alpha' must be positive.")
  }
  
  if (length(n) > 1) {
    n <- length(n)
  }
  if (is.na(n) || n <= 0) {
    stop("Sample size 'n' must be a positive integer.")
  }
  
  u <- stats::runif(n)
  x <- (1 - u^(1 / alpha))^(-0.5) - 1
  return(x)
}

#' @rdname ModToppLeone
#' @export
smtl <- function(x, alpha, log.p = FALSE) {
  return(pmtl(q = x, alpha = alpha, lower.tail = FALSE, log.p = log.p))
}

#' @rdname ModToppLeone
#' @export
hmtl <- function(x, alpha, log = FALSE) {
  pdf <- dmtl(x = x, alpha = alpha, log = FALSE)
  surv <- smtl(x = x, alpha = alpha, log.p = FALSE)
  
  hrf <- pdf / surv
  hrf[surv <= 0] <- Inf
  hrf[x <= 0] <- 0
  
  if (log) {
    return(log(hrf))
  } else {
    return(hrf)
  }
}
