#' Design-based confidence intervals for the AUC.
#' 
#' @param design An object of class \code{survey.design} generated by
#' \code{survey::svydesign} indicating the complex sampling design of the data.
#' @param response.var A character string with the name of the column indicating the response variable in the data set.
#' @param phat.var A character string with the name of the column indicating the estimated probabilities in the data set.
#' @param tag.event A character string indicating the label used to indicate the event of interest in \code{response.var}.
#' The default option is \code{tag.event = NULL}, which selects the class with the lowest number of units as event.
#' @param tag.nonevent A character string indicating the label used for non-event in \code{response.var}.
#' The default option is \code{tag.nonevent = NULL}, which selects the class with the greatest number of units as non-event.
#' @param method A character string indicating the method implemented to calculate the confidence interval: 
#' \code{method = 'JKn'} or \code{method = 'subbootstrap'}. Default is \code{method = 'JKn'}.
#' @param boot.B A numeric value indicating the number of bootstrap resamples to be considered. Default is \code{boot.B=1000}. Only for \code{method = 'subbootstrap'}. 
#' @param boot.ci Select \code{boot.ci = 'normal'} for standardized normal distribution-based confidence intervals 
#' and \code{boot.ci = 'quantile'} for confidence intervals based on quantiles. Default is \code{boot.ci = 'normal'}. Only for \code{method = 'subbootstrap'}.     
#' @param conf.level A numeric value between 0 and 1 indicating the confidence level. Default is \code{conf.level = 0.95}, resulting in a 95% CI.
#'
#' @return The output object of this function is a list of 2 elements containing the following information:
#' - `wauc`: a numeric value indicating the weighted point estimate of the AUC.
#' - `ci`: a numeric vector indicating the lower and upper values of the confidence interval.
#' 
#' @importFrom stats qnorm
#' @importFrom stats quantile
#' @importFrom stats weights
#' 
#' @references Iparragirre, A., Lumley, T., & Barrio, I. (2026). 
#' Design-Based Inference for the AUC with Complex Survey Data. 
#' arXiv, 2603.28320. 
#' (https://arxiv.org/abs/2603.28320)
#' 
#' @export
#'
#' @examples
#' \donttest{
#' mydesign <- survey::svydesign(ids = ~cluster, strata = ~strata, weights=~weights, 
#' data = example_variables_wroc, nest=TRUE)
#' m <- survey::svyglm(y ~ x1 + x2 + x3 + x4 + x5 + x6, design = mydesign, family = quasibinomial())
#' phat <- predict(m, newdata = example_variables_wroc, type = "response")
#' example_variables_wroc$phat <- phat
#' mydesign <- survey::svydesign(ids = ~cluster, strata = ~strata, weights = ~weights, 
#' data = example_variables_wroc, nest=TRUE)
#' 
#' # JKn-based confidence interval:
#' ci.JKn <- ci.wauc(design=mydesign, response.var = "y", phat.var = "phat", 
#'                   tag.event = 1, tag.nonevent = 0, method="JKn")
#' 
#' # Bootstrap-based confidence interval:
#' set.seed(123)
#' ci.boot <- ci.wauc(design=mydesign, response.var = "y", phat.var = "phat", 
#'                    tag.event = 1, tag.nonevent = 0, method="subbootstrap")
#' }
#' 

ci.wauc <- function(design, response.var, phat.var, tag.event = NULL, tag.nonevent = NULL,
                    method = c("JKn","subbootstrap"), boot.B=1000, boot.ci = c("normal", "quantile"), 
                    conf.level = 0.95){
  
  data <- get(design$call$data)
  weights <- as.character(design$call$weights[2])
  weights.var <- data[,weights]
  
  if(inherits(response.var, "character")){
    response.var <- data[,response.var]
  }
  
  if(length(table(response.var))!=2){stop("Response variable must have two classes.")}
  
  if(inherits(phat.var, "character")){
    phat.var <- data[,phat.var]
  }
  
  if(length(response.var) != length(phat.var) || length(response.var) != length(weights.var)){
    stop("Vectors indicating the responses, predicted probabilities and sampling weights must be the same length.")
  }
  
  # Missing tags:
  if(is.null(tag.nonevent)){
    if(is.null(tag.event)){
      tag.nonevent <- names(table(response.var)[which.max(table(response.var))])
      tag.event <- names(table(response.var)[which.min(table(response.var))])
    } else {
      tags <- names(table(response.var))
      tag.other <- which(tags == tag.event)
      tag.nonevent <- tags[-tag.other]
    }
  } else {
    if(is.null(tag.event)){
      tags <- names(table(response.var))
      tag.other <- which(tags == tag.nonevent)
      tag.event <- tags[-tag.other]
    }
  }
  
  method <- match.arg(method)
  boot.ci <- match.arg(boot.ci)
  
  alpha <- 1-conf.level
  
  # Point estimate:
  wauc <- wauc(response.var = response.var, phat.var = phat.var, weights.var = weights.var, tag.event = tag.event, tag.nonevent = tag.nonevent)$AUCw[1]
  
  if(method == "subbootstrap"){
    RB.boot.w <- weights(survey::as.svrepdesign(design = design, type = method, replicates=boot.B),"analysis")
    RB.aucw.b <- as.vector(apply(
      RB.boot.w, 2,
      function(x) wauc(
        response.var = response.var,
        phat.var = phat.var,
        weights.var = x,
        tag.event = tag.event,
        tag.nonevent = tag.nonevent
      )$AUCw[1]
    ))
    if(boot.ci == "normal"){
      var.RB <- var(RB.aucw.b)
      ci.l <- wauc - qnorm(alpha/2, lower.tail = FALSE)*sqrt(var.RB)
      ci.h <- wauc + qnorm(alpha/2, lower.tail = FALSE)*sqrt(var.RB)
    } else {
      if(boot.ci == "quantile"){
        ci.l <- as.vector(quantile(RB.aucw.b, probs = c(alpha/2)))
        ci.h <- as.vector(quantile(RB.aucw.b, probs = c(1-alpha/2)))
      }
    }
  } else {
    if(method == "JKn"){
      JKn.w <- weights(survey::as.svrepdesign(design = design, type = method),"analysis")
      JKn.aucw.1out <- as.vector(apply(
        JKn.w, 2,
        function(x) wauc(
          response.var = response.var,
          phat.var = phat.var,
          weights.var = x,
          tag.event = tag.event,
          tag.nonevent = tag.nonevent
        )$AUCw[1]
      ))
      strata_var <- attr(design$strata, "names")
      psu_var <- attr(design$cluster, "names")
      nclus.h <- table(unique(design$variables[,c(strata_var, psu_var)])[[strata_var]])
      id.0 <- apply(JKn.w==0, 2, which)
      strata_ids <- sapply(id.0, function(indexes) {
        unique(design$variables[indexes, strata_var])
      })
      ah <- nclus.h[as.character(strata_ids)]
      JKn.var <- sum(((ah-1)/ah)*((JKn.aucw.1out-wauc)^2))
      ci.l <- wauc - qnorm(alpha/2, lower.tail = FALSE)*sqrt(JKn.var)
      ci.h <- wauc + qnorm(alpha/2, lower.tail = FALSE)*sqrt(JKn.var)
    } else {
      stop("One of the following methods must be selected: method = 'JKn' or method = 'subbootstrap'.")
    }
  }
  
  obj <- list(wauc = wauc,
              ci = c(ci.l, ci.h))
  
  return(obj)
  
}