bolder_format_title <- function(text, level = c("title", "subtitle", "simple"), width = bolder_width()) {
  level <- match.arg(level)
  title <- bolder_clean_title(text)

  if (!nzchar(title)) {
    stop("The current line is empty.", call. = FALSE)
  }

  switch(
    level,
    title = paste(
      bolder_border(width),
      bolder_border(width),
      bolder_center(title, width = width, fill = "#"),
      bolder_border(width),
      bolder_border(width),
      sep = "\n"
    ),
    subtitle = paste(
      bolder_border(width),
      bolder_center(title, width = width, fill = "-", edge = "#"),
      bolder_border(width),
      sep = "\n"
    ),
    simple = bolder_inline(title, width = width)
  )
}

bolder_simple <- function() {
  bolder_replace_current_line("simple")
}

bolder_subtitle <- function() {
  bolder_replace_current_line("subtitle")
}

bolder_title <- function() {
  bolder_replace_current_line("title")
}

bolder_title_primary <- function() {
  bolder_title()
}

bolder_title_secondary <- function() {
  bolder_subtitle()
}

bolder_title_tertiary <- function() {
  bolder_simple()
}

bolder_width <- function(min_width = 63) {
  width <- getOption("bolder.width", getOption("width", 80L))
  width <- suppressWarnings(as.integer(width[[1]]))

  if (is.na(width) || width < 1) {
    width <- 80L
  }

  max(width, min_width)
}

bolder_replace_current_line <- function(level) {
  if (!rstudioapi::isAvailable()) {
    stop("This addin must be run inside RStudio.", call. = FALSE)
  }

  context <- rstudioapi::getActiveDocumentContext()

  if (length(context$selection) < 1) {
    stop("Could not find an active editor line.", call. = FALSE)
  }

  selection <- context$selection[[1]]
  row <- as.integer(selection$range$start[["row"]])

  if (is.na(row) || row < 1 || row > length(context$contents)) {
    stop("Could not identify the current line.", call. = FALSE)
  }

  line <- context$contents[[row]]
  replacement <- bolder_format_title(line, level = level)

  line_range <- rstudioapi::document_range(
    rstudioapi::document_position(row, 1),
    rstudioapi::document_position(row, nchar(line, type = "chars") + 1)
  )

  rstudioapi::modifyRange(line_range, replacement, id = context$id)
  invisible(replacement)
}

bolder_clean_title <- function(text) {
  text <- trimws(text)
  text <- sub("^#+\\s*", "", text)
  text <- sub("\\s*#?[-=#]+#?\\s*$", "", text)
  trimws(toupper(text))
}

bolder_border <- function(width) {
  strrep("#", width)
}

bolder_center <- function(title, width, fill, edge = "") {
  inner_width <- width - (2 * nchar(edge, type = "chars"))
  label <- paste0(" ", title, " ")

  if (nchar(label, type = "chars") > inner_width) {
    label <- substr(label, 1, inner_width)
  }

  free_space <- inner_width - nchar(label, type = "chars")
  left_fill <- floor(free_space / 2)
  right_fill <- ceiling(free_space / 2)

  paste0(
    edge,
    strrep(fill, left_fill),
    label,
    strrep(fill, right_fill),
    edge
  )
}

bolder_inline <- function(title, width) {
  label <- paste0("# ", title, " ")

  if (nchar(label, type = "chars") > width) {
    return(substr(label, 1, width))
  }

  paste0(label, strrep("-", width - nchar(label, type = "chars")))
}
