test_that("available_patterns is non-empty", {
  pats <- available_patterns()
  expect_true(is.character(pats))
  expect_gte(length(pats), 68)
  expect_gte(nrow(pattern_catalog()), 68)
})

test_that("demo_ohlcv returns valid structure", {
  d <- demo_ohlcv(80, seed = 42)
  expect_true(is.data.frame(d))
  expect_true(all(c("open", "high", "low", "close", "volume") %in% names(d)))
  expect_equal(nrow(d), 80)
})

test_that("single candle detectors return logical vectors", {
  d <- demo_ohlcv(100, seed = 101)
  out <- detect_pattern(d, "doji")
  expect_type(out, "logical")
  expect_length(out, nrow(d))
  out2 <- detect_pattern(d, "hammer")
  expect_type(out2, "logical")
  expect_length(out2, nrow(d))
})

test_that("common Chinese aliases are accepted", {
  d <- demo_ohlcv(120, seed = 99)
  out <- detect_pattern(d, "双针探底")
  expect_type(out, "logical")
  expect_length(out, nrow(d))
})

test_that("scan and screen APIs work on lists", {
  d1 <- demo_ohlcv(120, seed = 1)
  d2 <- demo_ohlcv(120, seed = 2)
  scans <- scan_patterns(d1, patterns = c("doji", "hammer"))
  expect_equal(nrow(scans), 2)

  res <- screen_symbols(
    list(AAA = d1, BBB = d2),
    pattern = "doji",
    latest_only = FALSE
  )
  expect_true(all(c("symbol", "pattern", "detected_index") %in% names(res)))
})

test_that("simulation demo builds charts and screening outputs", {
  out <- run_simulation_demo(
    symbols = c("AAA", "BBB"),
    patterns = c("double_bottom", "golden_pit"),
    n = 160,
    seed = 11,
    output_dir = tempdir()
  )
  expect_true(is.list(out))
  expect_true(all(c("data", "screen", "plot_files") %in% names(out)))
  expect_true(length(out$plot_files) >= 2)
  expect_true(all(file.exists(out$plot_files)))
})

test_that("all patterns are safe on short series", {
  d <- demo_ohlcv(35, seed = 777)
  pats <- available_patterns("id")
  for (p in pats) {
    out <- detect_pattern(d, p)
    expect_type(out, "logical")
    expect_length(out, nrow(d))
  }
})

test_that("rounded patterns handle small lookback", {
  d <- demo_ohlcv(80, seed = 42)
  rb <- detect_pattern(d, "rounded_bottom", lookback = 8)
  rt <- detect_pattern(d, "rounded_top", lookback = 8)
  expect_type(rb, "logical")
  expect_type(rt, "logical")
  expect_length(rb, nrow(d))
  expect_length(rt, nrow(d))
})
