#' @title SEQIC Indicator 4 - Autopsy and Long LOS Without Autopsy
#'
#' @description
#'
#' `r lifecycle::badge("experimental")`
#'
#' Computes SEQIC Indicator 4a and 4b for trauma center performance. Indicator
#' 4a captures the proportion of deceased trauma patients at trauma level I–IV
#' facilities who had an autopsy performed. Indicator 4b identifies deceased
#' trauma patients with a prolonged length of stay (LOS > 3 days) but without an
#' autopsy.
#'
#' @inheritParams seqic_indicator_1
#' @param ed_disposition Column representing the emergency department
#'   disposition. For a record to be picked up in this function, the ED
#'   dispostion must be documented as "Deceased/Expired".
#' @param ed_LOS Column for the calculated ED length of stay, measured in
#'   minutes.
#' @param hospital_disposition Column representing the hospital disposition. For
#'   a record to be picked up in this function, the hospital dispostion must be
#'   documented as "Deceased/Expired".
#' @param hospital_LOS Column for the calculated hospital length of stay,
#'   measured in minutes.
#' @param autopsy Unquoted column name indicating whether an autopsy was
#'   performed. Expected values: `"Yes"` or `NA`.
#' @inheritDotParams nemsqar::nemsqa_binomial_confint conf.level correct
#'
#' @details This function:
#' \itemize{
#'   \item Filters trauma records to those with a trauma center level of I–IV.
#'   \item Identifies records where the patient died, based on ED or hospital
#'   disposition.
#'   \item Deduplicates by `unique_incident_id` to ensure one record per
#'   incident.
#'   \item For Indicator 4a, calculates the proportion of deceased patients who
#'   received an autopsy.
#'   \item For Indicator 4b, calculates the proportion of deceased patients with
#'   a hospital or ED length of stay greater than 72 hours (4320 minutes) and no
#'   autopsy performed.
#' }
#'
#' @note
#'
#' Users must ensure appropriate column names are passed and data is
#' pre-processed to include the necessary fields without missing critical
#' identifiers or timestamps.
#'
#' @return A tibble summarizing SEQIC Indicator 4a and 4b results. Includes
#'   numerator, denominator, and performance rate for the indicator. 95%
#'   confidence intervals are provided optionally.
#'
#' @examples
#' # Packages
#' library(dplyr)
#' library(traumar)
#'
#' # Create a synthetic test dataset
#' test_data <- tibble::tibble(
#'   id = as.character(1:8),
#'   trauma_level = c("I", "II", "III", "IV", "I", "II", "III", "IV"),
#'   ed_disp = c(
#'     "Operating Room",
#'     "Admitted",
#'     "Deceased/Expired",
#'     "Transferred",
#'     "Deceased/Expired",
#'     "Deceased/Expired",
#'     "Admitted",
#'     "Deceased/Expired"
#'   ),
#'   ed_los = c(120, 200, 5000, 180, 3000, 4321, 60, 4000),
#'   hosp_disp = c(
#'     "Deceased/Expired",
#'     "Deceased/Expired",
#'     "Deceased/Expired",
#'     "Discharged",
#'     "Deceased/Expired",
#'     "Deceased/Expired",
#'     "Discharged",
#'     "Deceased/Expired"
#'   ),
#'   hosp_los = c(3000, 4500, 1000, 200, 5000, 4400, 150, 3000),
#'   autopsy_done = c("Yes", "No", "No", NA, "Yes", "No", NA, "Yes")
#' )
#'
#' # Run the indicator function
#' traumar::seqic_indicator_4(
#'   data = test_data,
#'   level = trauma_level,
#'   ed_disposition = ed_disp,
#'   ed_LOS = ed_los,
#'   hospital_disposition = hosp_disp,
#'   hospital_LOS = hosp_los,
#'   unique_incident_id = id,
#'   autopsy = autopsy_done
#' )
#'
#' @author Nicolas Foss, Ed.D., MS
#'
#' @export
seqic_indicator_4 <- function(
  data,
  level,
  included_levels = c("I", "II", "III", "IV"),
  ed_disposition,
  ed_LOS,
  hospital_disposition,
  hospital_LOS,
  unique_incident_id,
  autopsy,
  groups = NULL,
  calculate_ci = NULL,
  ...
) {
  ###___________________________________________________________________________
  ### Data validation ----
  ###___________________________________________________________________________

  # Validate if `data` is a data frame or tibble. ----
  validate_data_structure(
    input = data,
    structure_type = c("data.frame", "tbl", "tbl_df"),
    type = "error"
  )

  # make the `level` column accessible for validation ----
  level_check <- validate_data_pull(
    input = data,
    type = "error",
    col = {{ level }},
    var_name = "level"
  )

  # validate `level` ----
  validate_character_factor(
    input = level_check,
    type = "error",
    var_name = "level"
  )

  # Ensure that `ed_disposition` can be validated ----
  ed_disp_check <- validate_data_pull(
    input = data,
    col = {{ ed_disposition }},
    type = "error",
    var_name = "ed_disposition"
  )

  # Validate `ed_disposition` ----
  validate_character_factor(
    input = ed_disp_check,
    type = "error",
    var_name = "ed_disposition"
  )

  # Ensure that `hospital_disposition` can be validated ----
  hospital_disp_check <- validate_data_pull(
    input = data,
    col = {{ hospital_disposition }},
    type = "error",
    var_name = "hospital_disposition"
  )

  # Validate `hospital_disposition` ----
  validate_character_factor(
    input = hospital_disp_check,
    type = "error",
    var_name = "hospital_disposition"
  )

  # Ensure that ed_LOS can be validated ----
  ed_los_check <- validate_data_pull(
    input = data,
    col = {{ ed_LOS }},
    type = "error",
    var_name = "ed_LOS"
  )

  # Validate `ed_LOS` ----
  validate_numeric(
    input = ed_los_check,
    min = NULL,
    max = NULL,
    type = "error",
    var_name = "ed_LOS"
  )

  # Ensure `hospital_LOS` can be validated ----
  hospital_los_check <- validate_data_pull(
    input = data,
    col = {{ hospital_LOS }},
    type = "error",
    var_name = "hospital_LOS"
  )

  # Validate `hospital_LOS` ----
  validate_numeric(
    input = hospital_los_check,
    min = NULL,
    max = NULL,
    type = "error",
    var_name = "hospital_LOS"
  )

  # Ensure that `autopsy` can be validated ----
  autopsy_check <- validate_data_pull(
    input = data,
    col = {{ autopsy }},
    type = "error",
    var_name = "autopsy"
  )

  # Validate `autopsy` ----
  validate_character_factor(
    input = autopsy_check,
    type = "error",
    var_name = "autopsy"
  )

  # make the `unique_incident_id` column accessible for validation ----
  unique_incident_id_check <- validate_data_pull(
    input = data,
    type = "error",
    col = {{ unique_incident_id }},
    var_name = "unique_incident_id"
  )

  # Validate `unique_incident_id` ----
  validate_class(
    input = unique_incident_id_check,
    class_type = c("numeric", "integer", "character", "factor"),
    logic = "or",
    type = "error",
    var_name = "unique_incident_id"
  )

  # Check if all elements in groups are strings (i.e., character vectors) ----
  validate_character_factor(input = groups, type = "error", null_ok = TRUE)

  # Check if all `groups` exist in the `data` ----
  validate_names(
    input = data,
    check_names = groups,
    type = "error",
    var_name = "groups",
    null_ok = TRUE
  )

  # Validate the `calculate_ci` argument ----
  calculate_ci <- validate_choice(
    input = calculate_ci,
    choices = c("wilson", "clopper-pearson"),
    several.ok = FALSE,
    type = "error",
    null_ok = TRUE,
    var_name = "calculate_ci"
  )

  # Validate the `included_levels` argument ----
  validate_class(
    input = included_levels,
    class_type = c("numeric", "character", "factor", "integer"),
    type = "error",
    logic = "or"
  )

  ###___________________________________________________________________________
  ### Calculations ----
  ###___________________________________________________________________________

  ###___________________________________________________________________________
  # Indicator 4A - Presence of Autopsy in Deceased Patients at Trauma Centers
  ###___________________________________________________________________________
  seqic_4a <- data |>
    dplyr::filter(
      # Limit to valid trauma levels
      {{ level }} %in% included_levels,
      # Include cases where ED or hospital disposition is "Deceased/Expired"
      dplyr::if_any(
        c({{ ed_disposition }}, {{ hospital_disposition }}),
        ~ . == "Deceased/Expired"
      )
    ) |>
    # Ensure unique incidents (in case of duplicated records)
    dplyr::distinct({{ unique_incident_id }}, .keep_all = TRUE) |>
    # Compute numerator (autopsies = "Yes") and denominator
    dplyr::summarize(
      numerator_4a = sum({{ autopsy }} == "Yes", na.rm = TRUE),
      denominator_4a = dplyr::n(),
      seqic_4a = dplyr::if_else(
        denominator_4a > 0,
        numerator_4a / denominator_4a,
        NA_real_
      ),
      .by = {{ groups }}
    )

  # Optional confidence intervals for 4a ----
  if (!is.null(calculate_ci)) {
    seqic_4a <- seqic_4a |>
      dplyr::bind_cols(
        nemsqar::nemsqa_binomial_confint(
          data = seqic_4a,
          x = numerator_4a,
          n = denominator_4a,
          method = calculate_ci,
          ...
        ) |>
          dplyr::select(lower_ci, upper_ci) |>
          dplyr::rename(lower_ci_4a = lower_ci, upper_ci_4a = upper_ci)
      ) |>
      dplyr::relocate(lower_ci_4a, .after = seqic_4a) |>
      dplyr::relocate(upper_ci_4a, .after = lower_ci_4a)
  }

  ###___________________________________________________________________________
  # Indicator 4B - No Autopsy + Long LOS in Deceased Patients ----
  ###___________________________________________________________________________
  seqic_4b <- data |>
    dplyr::filter(
      {{ level }} %in% included_levels,
      dplyr::if_any(
        c({{ ed_disposition }}, {{ hospital_disposition }}),
        ~ . == "Deceased/Expired"
      ),
      # Long LOS (> 72 hours = 4320 minutes)
      dplyr::if_any(c({{ ed_LOS }}, {{ hospital_LOS }}), ~ . > 4320)
    ) |>
    dplyr::distinct({{ unique_incident_id }}, .keep_all = TRUE) |>
    # Numerator = no autopsy or autopsy not "Yes"
    dplyr::summarize(
      numerator_4b = sum(is.na({{ autopsy }}) | {{ autopsy }} != "Yes"),
      denominator_4b = dplyr::n(),
      seqic_4b = dplyr::if_else(
        denominator_4b > 0,
        numerator_4b / denominator_4b,
        NA_real_
      ),
      .by = {{ groups }}
    )

  # Optional confidence intervals for 4b ----
  if (!is.null(calculate_ci)) {
    seqic_4b <- seqic_4b |>
      dplyr::bind_cols(
        nemsqar::nemsqa_binomial_confint(
          data = seqic_4b,
          x = numerator_4b,
          n = denominator_4b,
          method = calculate_ci,
          ...
        ) |>
          dplyr::select(lower_ci, upper_ci) |>
          dplyr::rename(lower_ci_4b = lower_ci, upper_ci_4b = upper_ci)
      ) |>
      dplyr::relocate(lower_ci_4b, .after = seqic_4b) |>
      dplyr::relocate(upper_ci_4b, .after = lower_ci_4b)
  }

  # Combine 4a and 4b results; assign label for ungrouped reporting. ----
  if (is.null(groups)) {
    seqic_4 <- dplyr::bind_cols(
      seqic_4a,
      seqic_4b
    ) |>
      tibble::add_column(data = "population/sample", .before = "numerator_4a")
  } else {
    seqic_4 <- seqic_4a |>
      dplyr::full_join(seqic_4b, by = dplyr::join_by(!!!rlang::syms(groups))) |>
      dplyr::arrange(!!!rlang::syms(groups))
  }

  # Return the final summarized data for Indicator 4. ----
  return(seqic_4)
}
