#' Add indentations to row headers
#'
#' @param kable_input Output of `knitr::kable()` with `format` specified
#' @param positions A vector of numeric row numbers for the rows that need to
#' be indented.
#'
#' @examples x <- knitr::kable(head(mtcars), "html")
#' # Add indentations to the 2nd & 4th row
#' add_indent(x, c(2, 4))
#'
#' @export
add_indent <- function(kable_input, positions) {
  if (!is.numeric(positions)) {
    stop("Positions can only take numeric row numbers (excluding header rows).")
  }
  kable_format <- attr(kable_input, "format")
  if (!kable_format %in% c("html", "latex")) {
    warning("Please specify format in kable. kableExtra can customize either ",
            "HTML or LaTeX outputs. See https://haozhu233.github.io/kableExtra/ ",
            "for details.")
    return(kable_input)
  }
  if (kable_format == "html") {
    return(add_indent_html(kable_input, positions))
  }
  if (kable_format == "latex") {
    return(add_indent_latex(kable_input, positions))
  }
}

# Add indentation for LaTeX
add_indent_latex <- function(kable_input, positions) {
  table_info <- magic_mirror(kable_input)
  out <- enc2utf8(as.character(kable_input))

  if (table_info$duplicated_rows) {
    dup_fx_out <- fix_duplicated_rows_latex(out, table_info)
    out <- dup_fx_out[[1]]
    table_info <- dup_fx_out[[2]]
  }

  if (max(positions) > table_info$nrow - 1) {
    stop("There aren't that many rows in the table. Check positions in ",
         "add_indent_latex.")
  }

  for (i in positions) {
    rowtext <- table_info$contents[i + 1]
    out <- sub(rowtext, latex_indent_unit(rowtext), out, perl = TRUE)
    table_info$contents[i + 1] <- latex_indent_unit(rowtext)
  }
  out <- structure(out, format = "latex", class = "knitr_kable")
  attr(out, "kable_meta") <- table_info
  return(out)
}

latex_indent_unit <- function(rowtext) {
  paste0("\\\\hspace\\{1em\\}", rowtext)
}

# Add indentation for HTML
add_indent_html <- function(kable_input, positions) {
  kable_attrs <- attributes(kable_input)

  kable_xml <- read_kable_as_xml(kable_input)
  kable_tbody <- xml_tpart(kable_xml, "tbody")

  group_header_rows <- attr(kable_input, "group_header_rows")
  if (!is.null(group_header_rows)) {
    positions <- positions_corrector(positions, group_header_rows,
                                     length(xml_children(kable_tbody)))
  }
  for (i in positions) {
    node_to_edit <- xml_child(xml_children(kable_tbody)[[i]], 1)
    if (!xml_has_attr(node_to_edit, "indentLevel")) {
      xml_attr(node_to_edit, "style") <- paste(
        xml_attr(node_to_edit, "style"), "padding-left: 2em;"
      )
      xml_attr(node_to_edit, "indentLevel") <- 1
    } else {
      indentLevel <- as.numeric(xml_attr(node_to_edit, "indentLevel"))
      xml_attr(node_to_edit, "style") <- sub(
        paste0("padding-left: ", indentLevel * 2, "em;"),
        paste0("padding-left: ", (indentLevel + 1) * 2, "em;"),
        xml_attr(node_to_edit, "style")
      )
      xml_attr(node_to_edit, "indentLevel") <- indentLevel + 1
    }
  }
  out <- as_kable_xml(kable_xml)
  attributes(out) <- kable_attrs
  if (!"kableExtra" %in% class(out)) class(out) <- c("kableExtra", class(out))
  return(out)
}
