test_that("gglikert()", {
  skip_on_cran()
  skip_if_not_installed("labelled")
  skip_if_not_installed("ggplot2")
  skip_if_not_installed("dplyr")

  likert_levels <- c(
    "Strongly disagree",
    "Disagree",
    "Neither agree nor disagree",
    "Agree",
    "Strongly agree"
  )
  set.seed(42)
  df <-
    dplyr::tibble(
      q1 = sample(likert_levels, 150, replace = TRUE),
      q2 = sample(likert_levels, 150, replace = TRUE, prob = 5:1),
      q3 = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
      q4 = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
      q5 = sample(c(likert_levels, NA), 150, replace = TRUE),
      q6 = sample(likert_levels, 150, replace = TRUE, prob = c(1, 0, 1, 1, 0))
    ) |>
    dplyr::mutate(dplyr::across(
      dplyr::everything(),
      ~ factor(.x, levels = likert_levels)
    ))

  likert_levels_dk <- c(
    "Strongly disagree",
    "Disagree",
    "Neither agree nor disagree",
    "Agree",
    "Strongly agree",
    "Don't know"
  )
  df_dk <-
    dplyr::tibble(
      q1 = sample(likert_levels_dk, 150, replace = TRUE),
      q2 = sample(likert_levels_dk, 150, replace = TRUE, prob = 6:1),
      q3 = sample(likert_levels_dk, 150, replace = TRUE, prob = 1:6),
      q4 = sample(likert_levels_dk, 150, replace = TRUE, prob = 1:6),
      q5 = sample(c(likert_levels_dk, NA), 150, replace = TRUE),
      q6 = sample(
        likert_levels_dk, 150,
        replace = TRUE, prob = c(1, 0, 1, 1, 0, 1)
      )
    ) |>
    dplyr::mutate(dplyr::across(
      dplyr::everything(),
      ~ factor(.x, levels = likert_levels_dk)
    ))

  expect_doppelganger(
    "gglikert() mod simple",
    gglikert(df)
  )

  expect_no_error(
    d <- gglikert_data(df)
  )
  expect_equal(levels(d$.answer), likert_levels)

  expect_doppelganger(
    "gglikert() include and width",
    gglikert(df, include = q1:q3, width = .5)
  )

  expect_doppelganger(
    "gglikert() variable_labels",
    gglikert(df, variable_labels = c(q2 = "second question"))
  )

  expect_doppelganger(
    "gglikert() sort prop asc",
    gglikert(df, sort = "asc")
  )

  expect_doppelganger(
    "gglikert() sort prop desc",
    gglikert(df, sort = "desc")
  )

  expect_doppelganger(
    "gglikert() sort prop_lower asc",
    gglikert(df, sort = "asc", sort_method = "prop_lower")
  )

  expect_doppelganger(
    "gglikert() sort prop_lower desc",
    gglikert(df, sort = "desc", sort_method = "prop_lower")
  )

  expect_doppelganger(
    "gglikert() sort mean asc",
    gglikert(df, sort = "asc", sort_method = "mean")
  )

  expect_doppelganger(
    "gglikert() sort mean desc",
    gglikert(df, sort = "desc", sort_method = "mean")
  )

  expect_doppelganger(
    "gglikert() sort median asc",
    gglikert(df, sort = "asc", sort_method = "median")
  )

  expect_doppelganger(
    "gglikert() sort median desc",
    gglikert(df, sort = "desc", sort_method = "median")
  )

  expect_doppelganger(
    "gglikert() sort prop asc include_center",
    gglikert(df, sort = "asc", sort_prop_include_center = TRUE)
  )

  expect_doppelganger(
    "gglikert() exclude_fill_values",
    gglikert(df, exclude_fill_values = "Neither agree nor disagree")
  )

  expect_doppelganger(
    "gglikert() add_labels",
    gglikert(df, add_labels = FALSE)
  )

  expect_doppelganger(
    "gglikert() customize labels",
    gglikert(df, labels_size = 5, labels_hide_below = .3, labels_accuracy = .1)
  )

  expect_doppelganger(
    "gglikert() add_totals",
    gglikert(df, add_totals = FALSE)
  )

  expect_doppelganger(
    "gglikert() customize totals",
    gglikert(
      df,
      totals_size = 5,
      totals_fontface = "italic",
      totals_include_center = TRUE,
      totals_hjust = 0
    )
  )

  expect_doppelganger(
    "gglikert() colors",
    gglikert(df, labels_color = "red", totals_color = "blue")
  )

  expect_doppelganger(
    "gglikert() reverse",
    gglikert(df, y_reverse = TRUE, reverse_likert = TRUE)
  )

  expect_doppelganger(
    "gglikert() variable labels and y_label_wrap",
    df |>
      labelled::set_variable_labels(
        q1 = "first question",
        q2 = "second question",
        q3 = "third question with a very very very veru very very long label"
      ) |>
      gglikert(
        variable_labels = c(
          q2 = "question 2",
          q4 = "another question with a long long long long long long label"
        ),
        y_label_wrap = 20
      )
  )

  expect_doppelganger(
    "gglikert() cutoff 0",
    gglikert(df, cutoff = 0)
  )

  expect_doppelganger(
    "gglikert() cutoff 1",
    gglikert(df, cutoff = 1)
  )

  expect_doppelganger(
    "gglikert() cutoff 1 symmetric",
    gglikert(df, cutoff = 1, symmetric = TRUE)
  )

  expect_doppelganger(
    "gglikert() cutoff 1.5",
    gglikert(df, cutoff = 1.5)
  )

  expect_doppelganger(
    "gglikert() cutoff 5",
    gglikert(df, cutoff = 5)
  )

  expect_doppelganger(
    "gglikert_stacked()",
    gglikert_stacked(df)
  )

  expect_doppelganger(
    "gglikert_stacked() add_median_line",
    gglikert_stacked(df, add_median_line = TRUE)
  )

  expect_doppelganger(
    "gglikert_stacked() labels_color red",
    gglikert_stacked(df, labels_color = "red")
  )

  expect_doppelganger(
    "gglikert_stacked() labels_color auto",
    gglikert_stacked(df, labels_color = "auto")
  )

  expect_doppelganger(
    "gglikert_stacked() labels_color black",
    gglikert_stacked(df, labels_color = "black")
  )

  df_group <- df
  df_group$group1 <- sample(c("A", "B"), 150, replace = TRUE)
  df_group$group2 <- sample(c("a", "b", "c"), 150, replace = TRUE)

  expect_doppelganger(
    "gglikert() facet_cols",
    gglikert(df_group, q1:q6, facet_cols = vars(group1))
  )

  expect_doppelganger(
    "gglikert() facet_rows",
    gglikert(df_group, q1:q2, facet_rows = vars(group1, group2))
  )

  expect_doppelganger(
    "gglikert() facet_rows and facet_cols",
    gglikert(
      df_group, q3:q6,
      facet_cols = vars(group1), facet_rows = vars(group2)
    )
  )

  expect_doppelganger(
    "gglikert() facet_rows with group on y",
    gglikert(df_group, q1:q6, y = "group1", facet_rows = vars(.question))
  )

  f <- function(d) {
    d$.question <- forcats::fct_relevel(d$.question, "q5", "q2")
    d
  }
  expect_doppelganger(
    "gglikert() with data_fun",
    gglikert(df_group, q1:q6, data_fun = f)
  )
  expect_error(gglikert(df_group, data_fun = "text"))

  # testing compatibility with survey object
  skip_if_not_installed("survey")
  set.seed(42)
  df$w <- .5 + stats::runif(n = nrow(df))
  ds <- survey::svydesign(ids = ~ 1, weights = ~ w, data = df)
  expect_no_error(
    df |> gglikert_data(include = q1:q4, weights = w)
  )
  expect_no_error(
    ds |> gglikert_data(include = q1:q4)
  )
  expect_error(
    ds |> gglikert_data(include = q1:q4, weights = w)
  )
  expect_doppelganger(
    "gglikert() survey",
    gglikert(ds, q1:q4)
  )
  expect_doppelganger(
    "gglikert_stacked() survey",
    gglikert_stacked(ds, q1:q4)
  )
})

test_that("hex_bw()", {
  expect_equal(hex_bw("#FFFFFF"), "#000000")
  expect_equal(hex_bw("#BBBBBB"), "#000000")
  expect_equal(hex_bw("#000000"), "#ffffff")
  expect_equal(hex_bw("#444444"), "#ffffff")
})

test_that("gglikert_side()", {
  skip_on_cran()
  skip_if_not_installed("labelled")
  skip_if_not_installed("ggplot2")
  skip_if_not_installed("dplyr")

  likert_levels <- c(
    "Strongly disagree",
    "Disagree",
    "Neither agree nor disagree",
    "Agree",
    "Strongly agree"
  )
  set.seed(42)
  df <-
    dplyr::tibble(
      q1 = sample(likert_levels, 150, replace = TRUE),
      q2 = sample(likert_levels, 150, replace = TRUE, prob = 5:1),
      q3 = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
      q4 = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
      q5 = sample(c(likert_levels, NA), 150, replace = TRUE),
      q6 = sample(likert_levels, 150, replace = TRUE, prob = c(1, 0, 1, 1, 0))
    ) |>
    dplyr::mutate(dplyr::across(
      dplyr::everything(),
      ~ factor(.x, levels = likert_levels)
    ))

  likert_levels_dk <- c(
    "Strongly disagree",
    "Disagree",
    "Neither agree nor disagree",
    "Agree",
    "Strongly agree",
    "Don't know"
  )
  df_dk <-
    dplyr::tibble(
      q1 = sample(likert_levels_dk, 150, replace = TRUE),
      q2 = sample(likert_levels_dk, 150, replace = TRUE, prob = 6:1),
      q3 = sample(likert_levels_dk, 150, replace = TRUE, prob = 1:6),
      q4 = sample(likert_levels_dk, 150, replace = TRUE, prob = 1:6),
      q5 = sample(c(likert_levels_dk, NA), 150, replace = TRUE),
      q6 = sample(
        likert_levels_dk, 150,
        replace = TRUE, prob = c(1, 0, 1, 1, 0, 1)
      )
    ) |>
    dplyr::mutate(dplyr::across(
      dplyr::everything(),
      ~ factor(.x, levels = likert_levels_dk)
    ))

  expect_doppelganger(
    "gglikert_side() simple",
    gglikert_side(df, side_values = "Neither agree nor disagree")
  )

  expect_doppelganger(
    "gglikert_side() coord_ratio",
    gglikert_side(
      df,
      side_values = "Neither agree nor disagree",
      coord_ratio = 1 / 3
    )
  )

  expect_doppelganger(
    "gglikert_side() with options",
    gglikert_side(
      df,
      side_values = "Neither agree nor disagree",
      cutoff = 0,
      add_totals = FALSE
    )
  )
})
