#' @title ambiguity_table_to_GLstring
#'
#' @description A function that converts a data table of HLA allele ambiguities
#' (e.g. as created by `GLstring_expand_longer` or `GLstring_to_ambiguity_table`)
#' into a GL string format. The function processes the table by combining allele
#' ambiguities, haplotypes, gene copies, and loci into a structured GL string.
#'
#' @param data A data frame containing columns that represent possible gene
#' locations, loci, genotype ambiguities, genotypes, and haplotypes.
#'
#' @param remove_duplicates A logical value indicating if the function will check
#' for duplicate entries at each step and remove them before assembling the final
#' GL string. Useful if the ambiguity table has been altered, for example by
#' truncating allele designations. Default is FALSE.
#'
#' @return A GL string representing the combined gene locations, loci, genotype
#' ambiguities, genotypes, and haplotypes.
#'
#' @examples
#' # Example data frame input
#' data <- tibble::tribble(
#'   ~value, ~entry, ~possible_gene_location,
#'   ~locus, ~genotype_ambiguity, ~genotype, ~haplotype, ~allele,
#'   "HLA-A*01:01:01:01", 1, 1,
#'   1, 1, 1, 1, 1,
#'   "HLA-A*01:02", 1, 1,
#'   1, 1, 1, 1, 2,
#'   "HLA-A*01:03", 1, 1,
#'   1, 1, 1, 1, 3,
#'   "HLA-A*01:95", 1, 1,
#'   1, 1, 1, 1, 4,
#'   "HLA-A*24:02:01:01", 1, 1,
#'   1, 1, 2, 1, 1,
#'   "HLA-A*01:01:01:01", 1, 1,
#'   1, 2, 1, 1, 1,
#'   "HLA-A*01:03", 1, 1,
#'   1, 2, 1, 1, 2,
#'   "HLA-A*24:03:01:01", 1, 1,
#'   1, 2, 2, 1, 1,
#'   "HLA-B*07:01:01", 1, 1,
#'   2, 1, 1, 1, 1,
#'   "B*15:01:01", 1, 1,
#'   2, 1, 2, 1, 1,
#'   "B*15:02:01", 1, 1,
#'   2, 1, 2, 1, 2,
#'   "B*07:03", 1, 1,
#'   2, 2, 1, 1, 1,
#'   "B*15:99:01", 1, 1,
#'   2, 2, 2, 1, 1,
#'   "HLA-DRB1*03:01:02", 1, 1,
#'   3, 1, 1, 1, 1,
#'   "HLA-DRB5*01:01:01", 1, 1,
#'   3, 1, 1, 2, 1,
#'   "HLA-KIR2DL5A*0010101", 1, 1,
#'   3, 1, 2, 1, 1,
#'   "HLA-KIR2DL5A*0010201", 1, 1,
#'   3, 1, 3, 1, 1,
#'   "HLA-KIR2DL5B*0010201", 1, 2,
#'   1, 1, 1, 1, 1,
#'   "HLA-KIR2DL5B*0010301", 1, 2,
#'   1, 1, 2, 1, 1
#' )
#'
#' ambiguity_table_to_GLstring(data)
#'
#' @export
#'
#' @importFrom dplyr summarise
#' @importFrom dplyr pull
#' @importFrom dplyr %>%
#' @importFrom stringr str_flatten

ambiguity_table_to_GLstring <- function(data, remove_duplicates = FALSE) {
  # Validate inputs
  check_data_frame(data, "data")
  check_logical_flag(remove_duplicates, "remove_duplicates")

  # Helper to optionally deduplicate then collapse values at each GL string level.
  # Each level of the GL string hierarchy (allele, haplotype, genotype, etc.) follows
  # the same pattern: optionally remove duplicates, then summarise with a separator.
  collapse_level <- function(data, by_cols, collapse_char) {
    if (remove_duplicates) {
      data <- distinct(data, across(all_of(c("value", by_cols))), .keep_all = TRUE)
    }
    summarise(data, value = str_flatten(value, collapse = collapse_char), .by = all_of(by_cols))
  }

  # Collapse each level of the GL string hierarchy from most specific to least.
  # GL string separators: "/" (allele ambiguity), "~" (haplotype), "+" (gene copies),
  # "|" (genotype ambiguity), "^" (locus), "?" (possible gene location).
  data %>%
    collapse_level(c("entry", "possible_gene_location", "locus", "genotype_ambiguity", "genotype", "haplotype"), "/") %>%
    collapse_level(c("entry", "possible_gene_location", "locus", "genotype_ambiguity", "genotype"), "~") %>%
    collapse_level(c("entry", "possible_gene_location", "locus", "genotype_ambiguity"), "+") %>%
    collapse_level(c("entry", "possible_gene_location", "locus"), "|") %>%
    collapse_level(c("entry", "possible_gene_location"), "^") %>%
    collapse_level(c("entry"), "?") %>%
    pull(value)
}

globalVariables(c("."))
