test_that("txt_from_cat_mesos_plots returns text for meaningful differences", {
  # Create sample data with meaningful difference
  plot_data_1 <- data.frame(
    .variable_label = "Job satisfaction",
    .category = factor(
      c("Low", "Medium", "High"),
      levels = c("Low", "Medium", "High")
    ),
    .category_order = 1:3,
    .proportion = c(0.2, 0.3, 0.5)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Job satisfaction",
    .category = factor(
      c("Low", "Medium", "High"),
      levels = c("Low", "Medium", "High")
    ),
    .category_order = 1:3,
    .proportion = c(0.3, 0.4, 0.3)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  result <- saros::txt_from_cat_mesos_plots(plots, min_prop_diff = 0.10)

  expect_type(result, "character")
  expect_true(length(result) >= 1)
  expect_true(any(grepl("Job satisfaction", result)))
})

test_that("txt_from_cat_mesos_plots returns empty for small differences", {
  # Create sample data with small difference (below threshold)
  plot_data_1 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.5, 0.5)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.52, 0.48)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  result <- saros::txt_from_cat_mesos_plots(plots, min_prop_diff = 0.10)

  expect_type(result, "character")
  expect_equal(length(result), 0)
})

test_that("txt_from_cat_mesos_plots handles multiple variables", {
  # Create data with two variables
  plot_data_1 <- data.frame(
    .variable_label = rep(c("Var1", "Var2"), each = 2),
    .category = factor(rep(c("Low", "High"), 2), levels = c("Low", "High")),
    .category_order = rep(1:2, 2),
    .proportion = c(0.3, 0.7, 0.2, 0.8)
  )

  plot_data_2 <- data.frame(
    .variable_label = rep(c("Var1", "Var2"), each = 2),
    .category = factor(rep(c("Low", "High"), 2), levels = c("Low", "High")),
    .category_order = rep(1:2, 2),
    .proportion = c(0.5, 0.5, 0.6, 0.4)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  result <- saros::txt_from_cat_mesos_plots(plots, min_prop_diff = 0.15)

  expect_type(result, "character")
  expect_true(length(result) >= 1)
  # Should have summaries for variables with meaningful differences
  expect_true(any(grepl("Var1|Var2", result)))
})

test_that("txt_from_cat_mesos_plots handles flip_to_lowest_categories", {
  # Create data where lowest category differs
  plot_data_1 <- data.frame(
    .variable_label = "Question",
    .category = factor(
      c("Low", "Medium", "High"),
      levels = c("Low", "Medium", "High")
    ),
    .category_order = 1:3,
    .proportion = c(0.5, 0.3, 0.2)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Question",
    .category = factor(
      c("Low", "Medium", "High"),
      levels = c("Low", "Medium", "High")
    ),
    .category_order = 1:3,
    .proportion = c(0.3, 0.4, 0.3)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  result <- saros::txt_from_cat_mesos_plots(
    plots,
    flip_to_lowest_categories = TRUE,
    min_prop_diff = 0.10
  )

  expect_type(result, "character")
  expect_true(length(result) >= 1)
})

test_that("txt_from_cat_mesos_plots returns empty for NULL plots", {
  plots <- list(NULL, NULL)

  testthat::expect_warning(
    result <- saros::txt_from_cat_mesos_plots(plots),
    regexp = "elements 1 and 2 do not contain plot data"
  )

  expect_type(result, "character")
  expect_equal(length(result), 0)
})

test_that("txt_from_cat_mesos_plots respects n_highest_categories", {
  # Create data with 3 categories
  plot_data_1 <- data.frame(
    .variable_label = "Question",
    .category = factor(
      c("Low", "Med", "High"),
      levels = c("Low", "Med", "High")
    ),
    .category_order = 1:3,
    .proportion = c(0.2, 0.3, 0.5)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Question",
    .category = factor(
      c("Low", "Med", "High"),
      levels = c("Low", "Med", "High")
    ),
    .category_order = 1:3,
    .proportion = c(0.3, 0.3, 0.4)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  # Test with n_highest_categories = 2 (should combine Med + High)
  result <- saros::txt_from_cat_mesos_plots(
    plots,
    n_highest_categories = 2,
    min_prop_diff = 0.05
  )

  expect_type(result, "character")
  # Should mention multiple categories if combining them
  # The text will include both categories in selected_categories
})

test_that("txt_from_cat_mesos_plots uses custom templates", {
  plot_data_1 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.3, 0.7)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.4, 0.6)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  custom_template <- "CUSTOM: {var} shows {group_1} vs {group_2} for {selected_categories}"

  result <- saros::txt_from_cat_mesos_plots(
    plots,
    min_prop_diff = 0.05,
    glue_str_pos = custom_template,
    glue_str_neg = custom_template
  )

  expect_type(result, "character")
  if (length(result) > 0) {
    expect_true(any(grepl("CUSTOM:", result)))
  }
})

test_that("txt_from_cat_mesos_plots handles digits parameter", {
  plot_data_1 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.333, 0.667)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.444, 0.556)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  result_2_digits <- saros::txt_from_cat_mesos_plots(
    plots,
    min_prop_diff = 0.05,
    digits = 2
  )
  result_1_digit <- saros::txt_from_cat_mesos_plots(
    plots,
    min_prop_diff = 0.05,
    digits = 1
  )

  expect_type(result_2_digits, "character")
  expect_type(result_1_digit, "character")
})

test_that("txt_from_cat_mesos_plots handles selected_categories_last_split", {
  plot_data_1 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("A", "B", "C"), levels = c("A", "B", "C")),
    .category_order = 1:3,
    .proportion = c(0.2, 0.3, 0.5)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("A", "B", "C"), levels = c("A", "B", "C")),
    .category_order = 1:3,
    .proportion = c(0.3, 0.3, 0.4)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  result_or <- saros::txt_from_cat_mesos_plots(
    plots,
    n_highest_categories = 2,
    min_prop_diff = 0.05,
    selected_categories_last_split = " or "
  )

  result_and <- saros::txt_from_cat_mesos_plots(
    plots,
    n_highest_categories = 2,
    min_prop_diff = 0.05,
    selected_categories_last_split = " and "
  )

  expect_type(result_or, "character")
  expect_type(result_and, "character")
})

test_that("txt_from_cat_mesos_plots respects global settings", {
  # Ensure cleanup happens even if test fails
  withr::defer(saros::global_settings_reset())

  # Setup: Create sample data
  plot_data_1 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.3, 0.7)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.5, 0.5)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  # Set global settings
  saros::global_settings_set(
    new = list(
      min_prop_diff = 0.05,
      digits = 3
    ),
    fn_name = "txt_from_cat_mesos_plots",
    quiet = TRUE
  )

  # Call without explicit parameters - should use global settings
  result <- saros::txt_from_cat_mesos_plots(plots)

  # Should detect difference with min_prop_diff = 0.05 (0.7 - 0.5 = 0.2 > 0.05)
  expect_type(result, "character")
  expect_true(length(result) >= 1)

  # Reset global settings
  saros::global_settings_reset()

  # Without global settings and default min_prop_diff = 0.10, should still detect
  result_default <- saros::txt_from_cat_mesos_plots(plots)
  expect_type(result_default, "character")
  expect_true(length(result_default) >= 1)
})

test_that("explicit arguments override global settings", {
  # Ensure cleanup happens even if test fails
  withr::defer(saros::global_settings_reset())

  # Setup: Create sample data with small difference
  plot_data_1 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.4, 0.6)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Question",
    .category = factor(c("Low", "High"), levels = c("Low", "High")),
    .category_order = 1:2,
    .proportion = c(0.45, 0.55)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  # Set global settings with low threshold
  saros::global_settings_set(
    new = list(
      min_prop_diff = 0.01
    ),
    fn_name = "txt_from_cat_mesos_plots",
    quiet = TRUE
  )

  # Explicit argument should override (difference is 0.05, so 0.5 threshold means no text)
  result_explicit <- saros::txt_from_cat_mesos_plots(plots, min_prop_diff = 0.5)
  expect_type(result_explicit, "character")
  expect_equal(length(result_explicit), 0) # No text due to high threshold

  # Global settings should allow detection (0.05 > 0.01)
  result_global <- saros::txt_from_cat_mesos_plots(plots)
  expect_type(result_global, "character")
  expect_true(length(result_global) >= 1)
})

test_that("txt_from_cat_mesos_plots correctly handles second group proportions", {
  # Test for issue where second group (others) becomes zero
  plot_data_1 <- data.frame(
    .variable_label = rep("Var1", 3),
    .category = factor(
      c("Low", "Med", "High"),
      levels = c("Low", "Med", "High")
    ),
    .category_order = 1:3,
    .proportion = c(0.2, 0.3, 0.5)
  )

  plot_data_2 <- data.frame(
    .variable_label = rep("Var1", 3),
    .category = factor(
      c("Low", "Med", "High"),
      levels = c("Low", "Med", "High")
    ),
    .category_order = 1:3,
    .proportion = c(0.15, 0.42, 0.43)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  result <- saros::txt_from_cat_mesos_plots(plots, min_prop_diff = 0.01)

  expect_type(result, "character")
  # The result should contain non-zero values for both groups
  # Group 1 highest = 0.5, Group 2 highest = 0.43
  # Check that the text contains both values
  if (length(result) > 0) {
    expect_true(any(grepl("0\\.5", result)))
    expect_true(any(grepl("0\\.43", result)))
    # Should NOT show group_2 as 0
    expect_false(any(grepl("\\(0\\)", result)))
  }
})

test_that("txt_from_cat_mesos_plots avoids summing all categories for binary variables", {
  # Test for issue where n_highest_categories=2 with 2 categories sums to 1.0
  plot_data_1 <- data.frame(
    .variable_label = "Binary Question",
    .category = factor(c("No", "Yes"), levels = c("No", "Yes")),
    .category_order = 1:2,
    .proportion = c(0.4, 0.6)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Binary Question",
    .category = factor(c("No", "Yes"), levels = c("No", "Yes")),
    .category_order = 1:2,
    .proportion = c(0.7, 0.3)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  # With n_highest_categories = 2 on a binary variable
  result <- saros::txt_from_cat_mesos_plots(
    plots,
    n_highest_categories = 2,
    min_prop_diff = 0.05
  )

  expect_type(result, "character")
  # Should use only highest category (Yes), not sum of both
  if (length(result) > 0) {
    # Group 1 should show 0.6 (Yes only), not 1.0 (Yes + No)
    expect_true(any(grepl("0\\.6", result)))
    # Group 2 should show 0.3 (Yes only), not 1.0 (Yes + No)
    expect_true(any(grepl("0\\.3|0\\.7", result)))
    # Should NOT show 1.0 (which would be the sum)
    expect_false(any(grepl("\\(1\\)|\\(1\\.0\\)", result)))
  }
})

test_that("txt_from_cat_mesos_plots uses multiple categories when appropriate", {
  # Test that n_highest_categories=2 works correctly with 4+ categories
  plot_data_1 <- data.frame(
    .variable_label = "Four Category Question",
    .category = factor(
      c("VeryLow", "Low", "High", "VeryHigh"),
      levels = c("VeryLow", "Low", "High", "VeryHigh")
    ),
    .category_order = 1:4,
    .proportion = c(0.1, 0.2, 0.3, 0.4)
  )

  plot_data_2 <- data.frame(
    .variable_label = "Four Category Question",
    .category = factor(
      c("VeryLow", "Low", "High", "VeryHigh"),
      levels = c("VeryLow", "Low", "High", "VeryHigh")
    ),
    .category_order = 1:4,
    .proportion = c(0.2, 0.3, 0.25, 0.25)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  # With n_highest_categories = 2 and 4 categories, should combine High + VeryHigh
  result <- saros::txt_from_cat_mesos_plots(
    plots,
    n_highest_categories = 2,
    min_prop_diff = 0.05
  )

  expect_type(result, "character")
  # Should combine the two highest categories (High + VeryHigh)
  # Group 1: 0.3 + 0.4 = 0.7
  # Group 2: 0.25 + 0.25 = 0.5
  if (length(result) > 0) {
    expect_true(any(grepl("0\\.7", result)))
    expect_true(any(grepl("0\\.5", result)))
  }
})

test_that("txt_from_cat_mesos_plots handles multiple variables with different category counts", {
  # Test mixed scenario: one binary variable and one with many categories
  plot_data_1 <- data.frame(
    .variable_label = c(rep("Binary", 2), rep("FourCat", 4)),
    .category = factor(
      c("No", "Yes", "VeryLow", "Low", "High", "VeryHigh"),
      levels = c("No", "Yes", "VeryLow", "Low", "High", "VeryHigh")
    ),
    .category_order = c(1, 2, 1, 2, 3, 4),
    .proportion = c(0.4, 0.6, 0.1, 0.2, 0.3, 0.4)
  )

  plot_data_2 <- data.frame(
    .variable_label = c(rep("Binary", 2), rep("FourCat", 4)),
    .category = factor(
      c("No", "Yes", "VeryLow", "Low", "High", "VeryHigh"),
      levels = c("No", "Yes", "VeryLow", "Low", "High", "VeryHigh")
    ),
    .category_order = c(1, 2, 1, 2, 3, 4),
    .proportion = c(0.7, 0.3, 0.2, 0.3, 0.25, 0.25)
  )

  plots <- list(
    list(data = plot_data_1),
    list(data = plot_data_2)
  )

  result <- saros::txt_from_cat_mesos_plots(
    plots,
    n_highest_categories = 2,
    min_prop_diff = 0.05
  )

  expect_type(result, "character")
  # For Binary (2 categories), should use only highest (Yes): 0.6 vs 0.3
  # For FourCat (4 categories), should combine top 2: 0.7 vs 0.5
  if (length(result) > 0) {
    # Should contain results for at least one variable
    expect_true(any(grepl("Binary|FourCat", result)))
  }
})
test_that("txt_from_cat_mesos_plots handles mismatched variable label columns", {
  # Test for the bug where dat_1 uses .variable_label_original and
  # dat_2 uses .variable_label, causing group_2 to return 0

  # dat_1: variable name in .variable_label_original, .variable_label is empty
  plot_data_1 <- data.frame(
    .variable_label = "",
    .variable_label_original = "Question 1",
    .category = factor(c("Ja", "Nei"), levels = c("Nei", "Ja")),
    .category_order = c(1, 2),
    .proportion = c(0.4, 0.6),
    stringsAsFactors = FALSE
  )

  # dat_2: variable name in .variable_label, .variable_label_original is empty
  plot_data_2 <- data.frame(
    .variable_label = "Question 1",
    .variable_label_original = "",
    .category = factor(c("Ja", "Nei"), levels = c("Nei", "Ja")),
    .category_order = c(1, 2),
    .proportion = c(0.7, 0.3),
    stringsAsFactors = FALSE
  )

  plots <- list(plot_data_1, plot_data_2)

  result <- saros::txt_from_cat_mesos_plots(plots, min_prop_diff = 0.1)

  expect_type(result, "character")
  expect_true(length(result) >= 1)

  # Extract the proportions from the result text
  # Result should contain both group values (not 0 for group_2)
  expect_true(grepl("0.6", result[1])) # group_1 proportion
  expect_true(grepl("0.3", result[1])) # group_2 proportion (should NOT be 0!)

  # Ensure it doesn't show 0 for the second group
  expect_false(grepl("\\(0\\)", result[1]))
})

test_that("txt_from_cat_mesos_plots uses .variable_label_original to match crowds with different N suffixes", {
  # Regression test: when add_n_to_dep_label = TRUE, each crowd's .variable_label
  # gets a different "(N = X)" suffix appended, causing cross-crowd matching to
  # fail silently (group_2 proportion becomes 0). The fix saves the original label
  # in .variable_label_original before mutation so get_common_variable_label_column()
  # can use it as a stable join key.

  # dat_1 (target crowd, N=68): label has been suffixed with crowd-specific N
  # Row order: Valgt (order=1, prop=0.65), Ikke valgt (order=2, prop=0.35)
  # Function picks highest category_order → "Ikke valgt" with prop 0.35
  plot_data_1 <- data.frame(
    .variable_label = factor("Fagbrev (N = 68)", levels = "Fagbrev (N = 68)"),
    .variable_label_original = factor("Fagbrev", levels = "Fagbrev"),
    .category = factor(c("Valgt", "Ikke valgt"), levels = c("Valgt", "Ikke valgt")),
    .category_order = c(1L, 2L),
    .proportion = c(0.65, 0.35),
    stringsAsFactors = FALSE
  )

  # dat_2 (others crowd, N=1234): same variable but different N in the label
  # "Ikke valgt" (highest order) has proportion 0.10
  plot_data_2 <- data.frame(
    .variable_label = factor("Fagbrev (N = 1234)", levels = "Fagbrev (N = 1234)"),
    .variable_label_original = factor("Fagbrev", levels = "Fagbrev"),
    .category = factor(c("Valgt", "Ikke valgt"), levels = c("Valgt", "Ikke valgt")),
    .category_order = c(1L, 2L),
    .proportion = c(0.90, 0.10),
    stringsAsFactors = FALSE
  )

  plots <- list(list(data = plot_data_1), list(data = plot_data_2))

  result <- saros::txt_from_cat_mesos_plots(plots, min_prop_diff = 0.10)

  expect_type(result, "character")
  expect_true(length(result) >= 1, info = "Should produce at least one sentence")

  # group_2 proportion must NOT be 0 — the key regression assertion
  expect_false(
    grepl("\\(0\\)", result[1]),
    info = "group_2 proportion should not be 0 due to N-suffix label mismatch"
  )

  # Both crowd proportions should appear in the output
  expect_true(grepl("0.35", result[1], fixed = TRUE), info = "group_1 proportion (0.35) should appear")
  expect_true(grepl("0.1",  result[1], fixed = TRUE), info = "group_2 proportion (0.10) should appear")
})

test_that("txt_from_cat_mesos_plots uses checked category for checkbox variables (girafe fallback)", {
  # Auto-detection via girafe global settings (fallback path).
  old_girafe <- saros::global_settings_get("girafe")
  withr::defer(
    saros::global_settings_set(fn_name = "girafe", new = old_girafe, quiet = TRUE)
  )

  saros::global_settings_set(
    fn_name = "girafe",
    new = list(checked = "Valgt", not_checked = "Ikke valgt"),
    quiet = TRUE
  )

  # group_1 selects "Valgt" much more often; without the fix the function
  # would look at "Ikke valgt" (highest order) and report the opposite direction.
  plot_data_1 <- data.frame(
    .variable_label = "Checkbox item",
    .category = factor(c("Valgt", "Ikke valgt"), levels = c("Valgt", "Ikke valgt")),
    .category_order = c(1L, 2L),
    .proportion = c(0.70, 0.30),
    stringsAsFactors = FALSE
  )

  plot_data_2 <- data.frame(
    .variable_label = "Checkbox item",
    .category = factor(c("Valgt", "Ikke valgt"), levels = c("Valgt", "Ikke valgt")),
    .category_order = c(1L, 2L),
    .proportion = c(0.40, 0.60),
    stringsAsFactors = FALSE
  )

  plots <- list(list(data = plot_data_1), list(data = plot_data_2))

  result <- saros::txt_from_cat_mesos_plots(plots, min_prop_diff = 0.10)

  expect_type(result, "character")
  expect_length(result, 1L)
  expect_true(grepl("Valgt", result[1], fixed = TRUE),
    info = "Result should mention the checked category 'Valgt'")
  expect_false(grepl("Ikke valgt", result[1], fixed = TRUE),
    info = "Result should NOT be driven by the not_checked category")
  expect_true(grepl("0.7", result[1], fixed = TRUE))
  expect_true(grepl("0.4", result[1], fixed = TRUE))
})

test_that("txt_from_cat_mesos_plots uses checked/not_checked explicit parameters", {
  # Explicit checked/not_checked on the call — no global settings needed.

  plot_data_1 <- data.frame(
    .variable_label = "Checkbox item",
    .category = factor(c("Valgt", "Ikke valgt"), levels = c("Valgt", "Ikke valgt")),
    .category_order = c(1L, 2L),
    .proportion = c(0.70, 0.30),
    stringsAsFactors = FALSE
  )

  plot_data_2 <- data.frame(
    .variable_label = "Checkbox item",
    .category = factor(c("Valgt", "Ikke valgt"), levels = c("Valgt", "Ikke valgt")),
    .category_order = c(1L, 2L),
    .proportion = c(0.40, 0.60),
    stringsAsFactors = FALSE
  )

  plots <- list(list(data = plot_data_1), list(data = plot_data_2))

  result <- saros::txt_from_cat_mesos_plots(
    plots,
    checked = "Valgt",
    not_checked = "Ikke valgt",
    min_prop_diff = 0.10
  )

  expect_type(result, "character")
  expect_length(result, 1L)
  expect_true(grepl("Valgt", result[1], fixed = TRUE),
    info = "Explicit checked= should drive the comparison")
  expect_false(grepl("Ikke valgt", result[1], fixed = TRUE),
    info = "not_checked category should not appear in output")

  # Explicit params should also suppress checkbox handling when only one is set
  result_no_override <- saros::txt_from_cat_mesos_plots(
    plots,
    min_prop_diff = 0.10
  )
  # Without any global settings the function falls back to order-based selection
  # (highest order = "Ikke valgt"), which exceeds 0.10 diff in the other direction.
  # Just assert it produces a character result — the direction depends on defaults.
  expect_type(result_no_override, "character")
})
