# Create a mock 'rga' class object for testing
mock_rga_obj <- list(
  model = list(model = list(
    log_times = log(c(100, 200, 300, 400, 500)),
    log_cum_failures = log(c(1, 3, 6, 10, 15))
  )),
  fitted_values = c(1.5, 3.5, 6.5, 10.5, 15.5),
  lower_bounds = c(1.2, 3.2, 6.2, 10.2, 15.2),
  upper_bounds = c(1.8, 3.8, 6.8, 10.8, 15.8),
  breakpoints = c(200, 400)
)
class(mock_rga_obj) <- "rga"

# Unit tests
test_that("plotly_rga throws an error for incorrect input class", {
  incorrect_obj <- list(model = list(model = list()))
  expect_error(plotly_rga(incorrect_obj), "All inputs must be of class 'rga'.")
})

test_that("plotly_rga returns a plotly object", {
  plot <- plotly_rga(mock_rga_obj)
  expect_s3_class(plot, "plotly")
})

test_that("plotly_rga works with default parameters", {
  plot <- plotly_rga(mock_rga_obj)
  expect_true(!is.null(plot))
  expect_s3_class(plot, "plotly")
})

test_that("plotly_rga works with custom color parameters", {
  plot <- plotly_rga(mock_rga_obj, pointCol = "red", fitCol = "blue", confCol = "green", gridCol = "yellow", breakCol = "purple")
  expect_s3_class(plot, "plotly")
})

test_that("plotly_rga respects the showGrid parameter", {
  plot_with_grid <- plotly_rga(mock_rga_obj, showGrid = TRUE)
  plot_without_grid <- plotly_rga(mock_rga_obj, showGrid = FALSE)

  # Check if grid lines are reflected in the plot layout
  expect_equal(plot_with_grid$x$layoutAttrs[[1]]$xaxis$showgrid, TRUE)
  expect_equal(plot_with_grid$x$layoutAttrs[[1]]$yaxis$showgrid, TRUE)
  expect_equal(plot_without_grid$x$layoutAttrs[[1]]$xaxis$showgrid, FALSE)
  expect_equal(plot_without_grid$x$layoutAttrs[[1]]$yaxis$showgrid, FALSE)
})

test_that("plotly_rga includes hover text for data points", {
  plot <- plotly_rga(mock_rga_obj)
  hover_data <- plot$x$data[[1]]$text
  expect_true(all(grepl("Failures: \\(", hover_data)))
})

test_that("plotly_rga respects showConf = FALSE", {
  plot_with_conf <- plotly_rga(mock_rga_obj, showConf = TRUE)
  plot_without_conf <- plotly_rga(mock_rga_obj, showConf = FALSE)

  # With confidence: point + fit + lower + upper = 4 traces
  # Without confidence: point + fit = 2 traces
  expect_gt(length(plot_with_conf$x$attrs), length(plot_without_conf$x$attrs))
})

test_that("plotly_rga accepts a list of rga objects and returns a plotly object", {
  plot <- plotly_rga(list(mock_rga_obj, mock_rga_obj))
  expect_s3_class(plot, "plotly")
})

test_that("plotly_rga overlay produces more traces than single object", {
  single <- plotly_rga(mock_rga_obj)
  overlay <- plotly_rga(list(mock_rga_obj, mock_rga_obj))
  expect_gt(length(overlay$x$attrs), length(single$x$attrs))
})

test_that("plotly_rga overlay respects cols parameter", {
  plot <- plotly_rga(list(mock_rga_obj, mock_rga_obj), cols = c("red", "blue"))
  expect_s3_class(plot, "plotly")
})

test_that("plotly_rga throws error for non-rga input in list", {
  expect_error(
    plotly_rga(list(mock_rga_obj, list())),
    "All inputs must be of class 'rga'."
  )
})

test_that("plotly_rga works when breakpoints is NULL", {
  mock_no_bp <- mock_rga_obj
  mock_no_bp$breakpoints <- NULL
  plot <- plotly_rga(mock_no_bp)
  expect_s3_class(plot, "plotly")
})

test_that("plotly_rga respects custom main, xlab, ylab", {
  plot <- plotly_rga(mock_rga_obj, main = "My RGA", xlab = "Time", ylab = "Failures")
  expect_equal(plot$x$layoutAttrs[[1]]$title, "My RGA")
  expect_equal(plot$x$layoutAttrs[[1]]$xaxis$title, "Time")
  expect_equal(plot$x$layoutAttrs[[1]]$yaxis$title, "Failures")
})
