test_that("nrow_part or ncol_keys checks", {
  expect_error(nrow_part(12))
  expect_error(ncol_keys(12))
  ft <- flextable(head(iris))
  expect_equal(nrow_part(ft, part = "footer"), 0)
  expect_equal(nrow_part(ft, part = "body"), 6)
  expect_equal(ncol_keys(ft), 5)
})

test_that("add lines", {
  ft <- flextable(head(iris))

  newvals <- c("A", "B", "C", "D")

  ft <- add_header_lines(
    x = ft,
    values = newvals,
    top = TRUE
  )
  expect_equal(nrow_part(ft, part = "header"), 5)

  ft <- add_footer_lines(
    x = ft,
    values = newvals,
    top = FALSE
  )
  expect_equal(nrow_part(ft, part = "footer"), 4)

  x <- information_data_chunk(ft)

  header_sel <- x[x$.part %in% "header", ]
  expect_equal(
    header_sel$txt,
    c(
      rep(newvals, each = 5),
      colnames(iris)
    )
  )
  footer_sel <- x[x$.part %in% "footer", ]
  expect_equal(
    footer_sel$txt,
    rep(newvals, each = 5)
  )
})

test_that("separate_header", {
  x <- data.frame(
    Species = as.factor(c("setosa", "versicolor", "virginica")),
    Sepal.Length_mean_zzz = c(5.006, 5.936, 6.588),
    Sepal.Length_sd = c(0.35249, 0.51617, 0.63588),
    Sepal.Width_mean = c(3.428, 2.77, 2.974),
    Sepal.Width_sd_sfsf_dsfsdf = c(0.37906, 0.3138, 0.3225),
    Petal.Length_mean = c(1.462, 4.26, 5.552),
    Petal.Length_sd = c(0.17366, 0.46991, 0.55189),
    Petal.Width_mean = c(0.246, 1.326, 2.026),
    Petal.Width_sd = c(0.10539, 0.19775, 0.27465)
  )

  ft_1 <- flextable(x)
  ft_1 <- separate_header(x = ft_1, opts = c("span-top", "bottom-vspan"))
  header_txt <- information_data_chunk(ft_1)
  header_txt <- subset(header_txt, .part %in% "header")
  expect_equal(
    object = header_txt$txt,
    expected = c(
      "Species",
      "Sepal",
      "Sepal",
      "Sepal",
      "Sepal",
      "Petal",
      "Petal",
      "Petal",
      "Petal",
      "",
      "Length",
      "Length",
      "Width",
      "Width",
      "Length",
      "Length",
      "Width",
      "Width",
      "",
      "mean",
      "sd",
      "mean",
      "sd",
      "mean",
      "sd",
      "mean",
      "sd",
      "",
      "zzz",
      "",
      "",
      "sfsf",
      "",
      "",
      "",
      "",
      "",
      "",
      "",
      "",
      "dsfsdf",
      "",
      "",
      "",
      ""
    )
  )
})


test_that("add part rows", {
  ft01 <- fp_text_default(color = "red")
  ft02 <- fp_text_default(color = "orange")

  pars <- as_paragraph(
    as_chunk(c("(1)", "(2)"), props = ft02),
    " ",
    as_chunk(
      c(
        "My tailor is rich",
        "My baker is rich"
      ),
      props = ft01
    )
  )

  ft_1 <- flextable(head(mtcars))
  ft_1 <- add_header_row(ft_1, values = pars, colwidths = c(5, 6), top = FALSE)
  ft_1 <- add_body_row(ft_1, values = pars, colwidths = c(5, 6), top = TRUE)
  ft_1 <- add_footer_row(ft_1, values = pars, colwidths = c(3, 8), top = FALSE)

  x <- information_data_chunk(ft_1)

  new_header_sel <- x[
    x$.part %in% "header" & x$.row_id %in% 2 & x$.col_id %in% "mpg",
  ]
  expect_equal(new_header_sel$txt, c("(1)", " ", "My tailor is rich"))
  expect_equal(new_header_sel$color, c("orange", "black", "red"))
  new_header_sel <- x[
    x$.part %in% "header" & x$.row_id %in% 2 & x$.col_id %in% "wt",
  ]
  expect_equal(new_header_sel$txt, c("(2)", " ", "My baker is rich"))
  expect_equal(new_header_sel$color, c("orange", "black", "red"))
  spans <- flextable:::fortify_span(ft_1, parts = "header")
  expect_equal(
    spans$rowspan,
    c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0)
  )
  expect_true(all(spans$colspan %in% 1))
  expect_equal(
    colSums(is.na(ft_1$header$dataset)),
    rep(0L, ncol(mtcars)),
    ignore_attr = TRUE
  )

  new_body_sel <- x[
    x$.part %in% "body" & x$.row_id %in% 1 & x$.col_id %in% "mpg",
  ]
  expect_equal(new_body_sel$txt, c("(1)", " ", "My tailor is rich"))
  expect_equal(new_body_sel$color, c("orange", "black", "red"))
  new_body_sel <- x[
    x$.part %in% "body" & x$.row_id %in% 1 & x$.col_id %in% "wt",
  ]
  expect_equal(new_body_sel$txt, c("(2)", " ", "My baker is rich"))
  expect_equal(new_body_sel$color, c("orange", "black", "red"))
  spans <- flextable:::fortify_span(ft_1, parts = "body")
  spans <- spans[spans$.row_id %in% 1, ]
  expect_equal(
    spans$rowspan,
    c(5, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0)
  )
  expect_true(all(spans$colspan %in% 1))
  expect_equal(
    colSums(is.na(ft_1$body$dataset)),
    rep(1L, ncol(mtcars)),
    ignore_attr = TRUE
  )

  new_footer_sel <- x[
    x$.part %in% "footer" & x$.row_id %in% 1 & x$.col_id %in% "mpg",
  ]
  expect_equal(new_footer_sel$txt, c("(1)", " ", "My tailor is rich"))
  new_footer_sel <- x[
    x$.part %in% "footer" & x$.row_id %in% 1 & x$.col_id %in% "hp",
  ]
  expect_equal(new_header_sel$txt, c("(2)", " ", "My baker is rich"))
  spans <- flextable:::fortify_span(ft_1, parts = "footer")
  expect_equal(
    spans$rowspan,
    c(3, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0)
  )
  expect_true(all(spans$colspan %in% 1))
  expect_equal(
    colSums(is.na(ft_1$footer$dataset)),
    rep(0L, ncol(mtcars)),
    ignore_attr = TRUE
  )
})

test_that("add rows", {
  ft <- flextable(
    head(iris),
    col_keys = c(
      "Species",
      "Sepal.Length",
      "Petal.Length",
      "Sepal.Width",
      "Petal.Width"
    )
  )

  fun <- function(x) {
    paste0(
      c("min: ", "max: "),
      formatC(range(x))
    )
  }
  new_row <- list(
    Sepal.Length = fun(iris$Sepal.Length),
    Sepal.Width = fun(iris$Sepal.Width),
    Petal.Width = fun(iris$Petal.Width),
    Petal.Length = fun(iris$Petal.Length)
  )

  ft <- add_header(ft, values = new_row, top = FALSE)

  ft <- add_body(
    x = ft,
    Sepal.Length = 1:5,
    Sepal.Width = 1:5 * 2,
    Petal.Length = 1:5 * 3,
    Petal.Width = 1:5 + 10,
    Species = "Blah",
    top = FALSE
  )

  x <- information_data_chunk(ft)

  new_row_sel <- x[
    x$.part %in% "body" & x$.row_id %in% 7:11 & x$.col_id %in% "Species",
  ]
  expect_equal(new_row_sel$txt, rep("Blah", 5))

  new_row_sel <- x[
    x$.part %in% "body" & x$.row_id %in% 7:11 & x$.col_id %in% "Sepal.Length",
  ]
  expect_equal(new_row_sel$txt, as.character(1:5))

  expect_true(is.factor(ft$body$dataset[7:11, ]$Species))
  expect_equal(
    levels(ft$body$dataset[7:11, ]$Species),
    c("setosa", "versicolor", "virginica", "Blah")
  )
  expect_equal(as.character(ft$body$dataset[7:11, ]$Species), rep("Blah", 5))
  expect_equal(ft$body$dataset[7:11, ]$Sepal.Length, 1:5)

  new_header_sel <- x[
    x$.part %in% "header" & x$.row_id %in% 2:3 & x$.col_id %in% "Sepal.Width",
  ]
  expect_equal(new_header_sel$txt, c("min: 2", "max: 4.4"))
  new_header_sel <- x[
    x$.part %in% "header" & x$.row_id %in% 2:3 & x$.col_id %in% "Species",
  ]
  expect_equal(new_header_sel$txt, c("", ""))
})
