test_that("calculate_qc_metrics computes HTS metrics", {
  plate <- data.frame(
    experiment_type = c("negative_ctrl", "positive_cttl", "sample"),
    mean = c(1.00, 0.10, 0.60),
    sd = c(0.05, 0.03, 0.20)
  )
  out <- calculate_qc_metrics(plate)

  expect_named(out, c(
    "z_factor", "z_prime", "sb_value", "sn_value", "ssmd_value"
  ))
  expect_equal(out$z_factor, 1 - 3 * (0.05 + 0.20) / abs(1.00 - 0.60),
    tolerance = 1e-9)
  expect_equal(out$z_prime, 1 - 3 * (0.05 + 0.03) / abs(1.00 - 0.10),
    tolerance = 1e-9)
  expect_equal(out$sb_value, 1.00 / 0.10, tolerance = 1e-9)
  expect_equal(out$sn_value, (0.10 - 1.00) / 0.05, tolerance = 1e-9)
  expect_equal(
    out$ssmd_value,
    (0.10 - 1.00) / sqrt(0.03^2 + 0.05^2),
    tolerance = 1e-9
  )
})

test_that("calculate_qc_metrics errors on missing columns", {
  expect_error(
    calculate_qc_metrics(data.frame(experiment_type = "x", mean = 1)),
    "missing required"
  )
})

test_that("flag_qc_plates adds pass/fail flags", {
  qc <- data.frame(
    plateID = c("P01", "P02"),
    z_prime = c(0.62, 0.20),
    sb_value = c(5.1, 2.4),
    cv_negative_ctrl = c(6, 14)
  )
  out <- flag_qc_plates(qc)

  expect_equal(out$z_primer_flag, c("Normal", "Bad"))
  expect_equal(out$sb_flag, c("Normal", "Bad"))
  expect_equal(out$cv_flag, c("Normal", "Bad"))
})

test_that("flag_qc_plates only flags present columns", {
  qc <- data.frame(plateID = "P01", z_prime = 0.62)
  out <- flag_qc_plates(qc)
  expect_true("z_primer_flag" %in% names(out))
  expect_false("sb_flag" %in% names(out))
})
