#' Order (first, second, ...) formatting
#'
#' Format order.
#'
#' @param order value or vector of orders.
#' @param textual Return number as words. If `FALSE`, will run [insight::format_value()].
#' @param ... Arguments to be passed to [insight::format_value()] if `textual` is `FALSE`.
#'
#' @return A formatted string.
#' @examples
#' format_order(2)
#' format_order(8)
#' format_order(25, textual = FALSE)
#' @export
format_order <- function(order, textual = TRUE, ...) {
  if (textual) {
    order <- insight::format_number(order)
    parts <- unlist(strsplit(order, " ", fixed = TRUE))
    parts[length(parts)] <- switch(utils::tail(parts, 1),
      one = "first",
      two = "second",
      three = "third",
      four = "fourth",
      five = "fifth",
      six = "sixth",
      seven = "seventh",
      eight = "eigth",
      nine = "ninth"
    )
    out <- paste(parts, collapse = " ")
  } else {
    number <- insight::format_value(order, digits = 0, ...)
    last <- substr(number, nchar(number), nchar(number))
    last_two <- substr(number, nchar(number) - 1, nchar(number))
    # exceptions
    if (last_two %in% c(11, 12, 13)) {
      out <- paste0(number, "th")
    } else {
      out <- paste0(
        number,
        switch(last,
          `1` = "st",
          `2` = "nd",
          `3` = "rd",
          `4` = "th",
          `5` = "th",
          `6` = "th",
          `7` = "th",
          `8` = "th",
          `9` = "th",
          `0` = "th"
        )
      )
    }
  }

  out
}
