#' Plot PC axes
#'
#' `plot()` visualizes the relationship between a PCO axis and the vertebra or between pairs of PCO axes.
#'
#' @param x a `regions_pco` object; the output of a call to [svdPCO()].
#' @param pc_y,pc_x number; PC score indices for the y- and x-axes, respectively. `pc_x` can be `NULL`.
#' @param ... arguments passed to [ggplot2::geom_text()] when `pc_x` is not `NULL`. If `scores` is supplied as an argument, it will replace `pc_y` if unspecified.
#'
#' @return A `ggplot` object.
#'
#' @details
#' When `pc_x` is `NULL` (the default), `plot()` will display a scatterplot of the PCO axis identified by `pc_y` and vertebra position using [ggplot2::geom_point()]. This plot is similar to that generated by [plotsegreg()]. Otherwise, `plot()` uses [ggplot2::geom_text()] to identify vertebrae positions in the space corresponding to the requested PCOs.
#'
#' @seealso
#'
#' [svdPCO()] for generating the PCO scores. [plot.regions_sim()] for plotting PCO scores against vertebra position for simulated PCOs. [plotsegreg()] for plotting PCO scores against vertebra position after selecting breakpoints for a segmented regression.
#'
#' @example man/examples/example-svdPCO.R

#' @exportS3Method plot regions_pco
plot.regions_pco <- function(x, pc_y = 1, pc_x = NULL, ...) {

  if (identical(pc_y, formals()$pc_y)) {
    dotnames <- ...names()
    if ("scores" %in% dotnames) {
      scores <- ...elt(which(dotnames == "scores")[1L])
      arg::arg_whole_numeric(scores)
      if (!is.null(pc_x) && length(pc_y) > 1L) {
        arg::err("{.arg scores} can only have length 1 when {.arg pc_x} is specified")
      }
      arg::arg_between(scores, c(1, ncol(x[["scores"]])))
      pc_y <- scores
    }
  }

  pos <- .get_pos(x)
  specimen <- attr(x, "specimen")

  if (is.null(pc_x)) {
    arg::arg_whole_numeric(pc_y)
    arg::arg_between(pc_y, c(1, ncol(x[["scores"]])))

    pc_y <- sort(pc_y)

    Yvar <- x[["scores"]][, pc_y, drop = FALSE]

    # Plot PCO against vertebrae using plotsegreg() machinery
    return(.plotreg_internal(Xvar = pos, Yvar = Yvar, lines = FALSE,
                             scores = pc_y, specimen = specimen))
  }

  arg::arg_whole_numeric(pc_y)
  if (length(pc_y) > 1) {
    arg::err("{.arg pc_y} can only have length 1 when {.arg pc_x} is specified")
  }
  arg::arg_between(pc_y, c(1, ncol(x[["scores"]])))

  Yvar <- x[["scores"]][, pc_y]

  arg::arg_whole_number(pc_x)
  arg::arg_between(pc_x, c(1, ncol(x[["scores"]])))

  Xvar <- x[["scores"]][, pc_x]

  p <- ggplot(mapping = aes(x = Xvar,
                            y = Yvar,
                            label = pos,
                            color = if (nlevels(specimen) > 1) specimen)) +
    geom_text(...) +
    geom_point(alpha = 0) +
    theme_bw() +
    guides(color = guide_legend(override.aes = aes(label = "", alpha = 1))) +
    labs(x = paste("PC", pc_x),
         y = paste("PC", pc_y),
         color = NULL)

  p
}
