#' @title Simple scatterplot
#'
#' @param df A data frame.
#' @param x A quoted numeric column.
#' @param y A quoted numeric column.
#' @param group Some quoted grouping categorical column, e.g. administrative areas or population groups.
#' @param facet Some quoted grouping categorical column.
#' @param facet_scales Character. Either "free" (default) or "fixed" for facet scales.
#' @param x_rm_na Remove NAs in x?
#' @param y_rm_na Remove NAs in y?
#' @param group_rm_na Remove NAs in group?
#' @param facet_rm_na Remove NAs in facet?
#' @param add_color Add a color to points (if no grouping).
#' @param add_color_guide Should a legend be added?
#' @param flip TRUE or FALSE.
#' @param alpha Fill transparency.
#' @param size Point size.
#' @param x_title The x scale title. Default to NULL.
#' @param y_title The y scale title. Default to NULL.
#' @param group_title The group legend title. Default to NULL.
#' @param title Plot title. Default to NULL.
#' @param subtitle Plot subtitle. Default to NULL.
#' @param caption Plot caption. Default to NULL.
#' @param theme_fun Whatever theme. Default to theme_point(). NULL if no theming needed.
#'
#' @inheritParams scale_color_visualizer_discrete
#'
#' @export
point <- function(
  df,
  x,
  y,
  group = "",
  facet = "",
  facet_scales = "free",
  x_rm_na = TRUE,
  y_rm_na = TRUE,
  group_rm_na = TRUE,
  facet_rm_na = TRUE,
  add_color = color("cat_5_main_1"),
  add_color_guide = TRUE,
  flip = TRUE,
  alpha = 1,
  size = 2,
  x_title = NULL,
  y_title = NULL,
  group_title = NULL,
  title = NULL,
  subtitle = NULL,
  caption = NULL,
  theme_fun = theme_point(),
  scale_fill_fun = scale_fill_visualizer_discrete(),
  scale_color_fun = scale_color_visualizer_discrete()
) {
  #------ Checks

  # df is a data frame
  checkmate::assert_data_frame(df)

  # x and y and group are character
  checkmate::assert_character(x, len = 1)
  checkmate::assert_character(y, len = 1)
  checkmate::assert_character(group, len = 1)

  # x and y are columns in df
  checkmate::assert_choice(x, colnames(df))
  checkmate::assert_choice(y, colnames(df))
  if (group != "") {
    checkmate::assert_choice(group, colnames(df))
  }

  # x_rm_na, y_rm_na and group_rm_na are logical scalar
  checkmate::assert_logical(x_rm_na, len = 1)
  checkmate::assert_logical(y_rm_na, len = 1)
  checkmate::assert_logical(group_rm_na, len = 1)
  checkmate::assert_logical(facet_rm_na, len = 1)

  # facet_scales is a character scalar in c("free", "fixed")
  checkmate::assert_choice(facet_scales, c("free", "fixed"))

  # flip is a logical scalar
  checkmate::assert_logical(flip, len = 1)

  # alpha is a numeric scalar between 0 and 1
  checkmate::assert_numeric(alpha, lower = 0, upper = 1, len = 1)

  # size is a numeric scalar
  checkmate::assert_numeric(size, len = 1)

  # x and y are numeric
  if (!any(c("numeric", "integer") %in% class(df[[x]]))) {
    rlang::abort(paste0(x, " must be numeric."))
  }
  if (!any(c("numeric", "integer") %in% class(df[[y]]))) {
    rlang::abort(paste0(y, " must be numeric."))
  }

  #----- Data wrangling

  # facets over group
  if (group != "" && facet != "" && group == facet) {
    rlang::warn("'group' and 'facet' are the same identical.")
  }

  # remove NAs using base R
  if (x_rm_na) {
    df <- df[!(is.na(df[[x]])), ]
  }
  if (y_rm_na) {
    df <- df[!(is.na(df[[y]])), ]
  }
  if (group != "" && group_rm_na) {
    df <- df[!(is.na(df[[group]])), ]
  }
  if (facet != "" && facet_rm_na) {
    df <- df[!(is.na(df[[facet]])), ]
  }

  # prepare aes
  if (group != "") {
    g <- ggplot2::ggplot(
      df,
      mapping = ggplot2::aes(
        x = !!rlang::sym(x),
        y = !!rlang::sym(y),
        fill = !!rlang::sym(group),
        color = !!rlang::sym(group)
      )
    )
  } else {
    g <- ggplot2::ggplot(
      df,
      mapping = ggplot2::aes(
        x = !!rlang::sym(x),
        y = !!rlang::sym(y)
      )
    )
  }

  # add title, subtitle, caption, x_title, y_title
  g <- g +
    ggplot2::labs(
      title = title,
      subtitle = subtitle,
      caption = caption,
      x = x_title,
      y = y_title,
      color = group_title,
      fill = group_title
    )

  # facets
  # facets
  if (facet != "") {
    if (flip) {
      g <- g +
        ggplot2::facet_grid(
          rows = ggplot2::vars(!!rlang::sym(facet)),
          scales = facet_scales,
          space = if (facet_scales == "free") "free_y" else "fixed"
        )
    } else {
      g <- g +
        ggplot2::facet_grid(
          cols = ggplot2::vars(!!rlang::sym(facet)),
          scales = facet_scales,
          space = if (facet_scales == "free") "free_x" else "fixed"
        )
    }
  }

  # Should the graph use position_fill?
  if (group != "") {
    g <- g +
      ggplot2::geom_point(
        alpha = alpha,
        size = size
      )
  } else {
    g <- g +
      ggplot2::geom_point(
        alpha = alpha,
        size = size,
        color = add_color
      )
  }

  if (flip) {
    g <- g + ggplot2::coord_flip()
  }

  # Remove guides for legend if !add_color_guide
  if (!add_color_guide) {
    g <- g + ggplot2::guides(fill = "none", color = "none")
  }

  # Add theme
  if (!is.null(theme_fun)) {
    g <- g + theme_fun
  }

  # Add scale fun
  if (!is.null(scale_fill_fun)) {
    g <- g + scale_fill_fun
  }

  if (!is.null(scale_color_fun)) {
    g <- g + scale_color_fun
  }

  return(g)
}
