#==========================================================
# Constant Variable Check
#==========================================================

#' Check Constant Variables
#'
#' Identifies variables that contain no meaningful
#' variation.
#'
#' @param data A data.frame.
#'
#' @return A data.frame of class \code{ConstantCheck}
#'   containing the number of unique non-missing values,
#'   missing values, and constant-variable status for each
#'   variable.
#'
#' @details
#' A variable is classified as constant when it contains
#' one or fewer unique non-missing values.
#'
#' Missing values are excluded when counting unique values.
#' Consequently, a variable containing only missing values
#' is also classified as constant.
#'
#' @examples
#' dat <- data.frame(
#'   id = 1:5,
#'   group = rep("A", 5),
#'   value = c(10, 10, 10, NA, 10)
#' )
#'
#' constant_check(dat)
#'
#' @export

constant_check <- function(data) {

  #---------------------------------------------
  # Validation
  #---------------------------------------------
  validate_data(data)

  #---------------------------------------------
  # Number of unique non-missing values
  #---------------------------------------------
  unique_values <- vapply(
    data,
    function(x) {

      length(
        unique(
          x[!is.na(x)]
        )
      )

    },
    integer(1)
  )

  #---------------------------------------------
  # Missing values
  #---------------------------------------------
  missing_values <- vapply(
    data,
    function(x) {
      sum(is.na(x))
    },
    integer(1)
  )

  #---------------------------------------------
  # Constant status
  #---------------------------------------------
  constant <- unique_values <= 1L

  #---------------------------------------------
  # Result
  #---------------------------------------------
  result <- data.frame(
    Variable = names(data),
    UniqueValues = unname(unique_values),
    Missing = unname(missing_values),
    Constant = unname(constant),
    stringsAsFactors = FALSE,
    check.names = FALSE
  )

  #---------------------------------------------
  # Class
  #---------------------------------------------
  class(result) <- c(
    "ConstantCheck",
    "data.frame"
  )

  result
}
