transform <- function(X, transformation) {
  if (transformation == "MCA") {
    X_transformed <- FactoMineR::MCA(X, ncp = Inf, graph = FALSE)
  } else {
    X_transformed <- FactoMineR::FAMD(X, ncp = Inf, graph = FALSE)
  }

  ncp95 <- sum(X_transformed$eig[, 3] < 95)
  if (is.na(ncp95)) {
    stop("Error: No valid components found to meet the threshold.")
  }

  X_transformed <- (X_transformed$ind$coord[, 1:ncp95, drop = FALSE])

  return(X_transformed)
}

preprocess <- function(base, covariate_names, treatment_name, transformation) {
  X <- base[, covariate_names, drop = FALSE]

  X_transformed <- transform(X, transformation)

  # Drop columns corresponding to X
  preprocessed_data <- base[, !(names(base) %in% covariate_names)]

  # Add columns corresponding to Xfamd
  preprocessed_data <- cbind(X_transformed, preprocessed_data)

  # Write the matching formula accordingly
  if (transformation == "FAMD") {
    dims <- paste("Dim", 1:NCOL(X_transformed), sep = ".")
    matching_formula <- stats::as.formula(
      paste(treatment_name, "~", paste(dims, collapse = " + "))
    )
  } else {
    dims <- paste0("`", colnames(X_transformed), "`")
    matching_formula <- stats::as.formula(
      paste(treatment_name, "~", paste(dims, collapse = " + "))
    )
  }

  return(list(
    preprocessed_data = preprocessed_data,
    matching_formula = matching_formula
  ))
}
