#' Search a Term-Frequency Table
#'
#' @description Search a term-frequency table by pattern or frequency.
#'
#' @param x 'character' string.
#'   Regular-expression pattern to search for among the table's terms.
#'
#' @param data 'term' and 'data.frame' class.
#'   Term-frequency table to search, with columns `term`, `pub_id`, and `freq`.
#'   Defaults to the term frequencies from the INLPO publications; see the [`terms`]
#'   dataset for details.
#'
#' @param ignore_case 'logical' flag.
#'   Whether to ignore character case when matching. Defaults to `TRUE`.
#'
#' @param ...
#'   Additional arguments passed to [grep()] (for example, `fixed` or `perl`).
#'
#' @param low_freq 'numeric' number.
#'   Lower frequency bound; terms occurring fewer than this many times are excluded.
#'   Defaults to 1.
#'
#' @param high_freq 'numeric' number.
#'   Upper frequency bound; terms occurring more than this many times are excluded.
#'   Defaults to `Inf` (no upper limit).
#'
#' @param simplify 'logical' flag.
#'   Whether to return only the unique publication identifiers (`TRUE`, the default)
#'   rather than the full table of matching rows.
#'
#' @return If `simplify = TRUE`, a 'character' vector of unique publication
#'   identifiers, ordered by the most frequent matching term first. If
#'   `simplify = FALSE`, a 'data.frame' of matching rows sorted by decreasing
#'   frequency.
#'
#' @author J.C. Fisher, U.S. Geological Survey, Idaho Water Science Center
#'
#' @export
#'
#' @seealso [`mine_text`] to build a term-frequency table.
#'
#' @examples
#' search_terms("mlms")
#'
#' out <- search_terms("mlms", simplify = FALSE)
#' head(out)

search_terms <- function(
  x,
  data = inlpubs::terms,
  ignore_case = TRUE,
  ...,
  low_freq = 1,
  high_freq = Inf,
  simplify = TRUE
) {
  # check arguments
  checkmate::assert_string(x, na.ok = FALSE)
  checkmate::assert_class(data, classes = c("term", "data.frame"))
  checkmate::assert_flag(ignore_case)
  checkmate::assert_number(low_freq, lower = 1)
  checkmate::assert_number(high_freq, lower = low_freq)
  checkmate::assert_flag(simplify)

  # select rows whose term matches the search pattern
  matched <- grepl(pattern = x, data$term, ignore.case = ignore_case, ...)
  out <- data[matched, ]

  # restrict to the requested frequency range
  in_range <- out$freq >= low_freq & out$freq <= high_freq
  out <- out[in_range, ]

  # sort by decreasing frequency, then publication identifier
  idxs <- order(out$freq, out$pub_id, decreasing = c(TRUE, FALSE), method = "radix")
  out <- out[idxs, ]

  # drop unused factor levels
  out <- droplevels(out)

  # optionally reduce to unique publication identifiers
  if (simplify) {
    out <- out$pub_id |>
      as.character() |>
      unique()
  }

  out
}
