############################################
##  Homogeneity of variance test
############################################

#' @export
homo_variance_test <- function(dataset, var, group,
                               method = c("levene", "bartlett", "fligner"),
                               data_filter = "",
                               envir = parent.frame()) {
  
  # 获取数据
  df_name <- if (is_string(dataset)) dataset else deparse(substitute(dataset))
  dataset <- get_data(
    dataset, 
    vars = c(var, group),
    filt = data_filter, 
    na.rm = FALSE, 
    envir = envir
  )
  
  # 校验变量存在性
  if (!var %in% colnames(dataset)) {
    stop(paste("变量", var, "未在数据集中找到！"), call. = FALSE)
  }
  if (!group %in% colnames(dataset)) {
    stop(paste("分组变量", group, "未在数据集中找到！"), call. = FALSE)
  }
  
  # 提取变量
  x <- dataset[[var]]
  g_raw <- dataset[[group]]
  
  # 校验数值变量类型
  if (!is.numeric(x)) {
    stop(paste("变量", var, "必须是数值型！"), call. = FALSE)
  }
  
  # 计算有效样本
  valid_indices <- !is.na(g_raw) & !is.na(x)
  valid_data <- dataset[valid_indices, ]  # 保留有效样本的完整数据（用于绘图）
  valid_g <- g_raw[valid_indices]
  valid_levels <- length(unique(valid_g))
  
  # 数据不足判断
  if (valid_levels < 2) {
    return(structure(
      list(
        df_name = df_name,
        var = var,
        group = group,
        valid_data = valid_data,  # 传递有效数据用于绘图提示
        res = tibble(
          Test = "无法执行检验",
          Statistic = NA_real_,
          p.value = NA_character_
        )
      ),
      class = "homo_variance_test"
    ))
  }
  
  # 转换分组为因子
  g <- factor(valid_g)
  
  # 检验计算
  res <- tibble::tibble(
    Test = character(),
    Statistic = numeric(),
    p.value = numeric()
  )
  
  # Levene检验
  if ("levene" %in% method && requireNamespace("car", quietly = TRUE)) {
    tmp <- tryCatch(car::leveneTest(x[valid_indices] ~ g), error = function(e) NULL)
    if (!is.null(tmp) && nrow(tmp) > 0) {
      res <- tibble::add_row(res,
                             Test = "Levene",
                             Statistic = as.numeric(tmp[["F value"]][1]),
                             p.value = as.numeric(tmp[["Pr(>F)"]][1]))
    }
  }
  
  # Bartlett检验
  if ("bartlett" %in% method) {
    tmp <- tryCatch(stats::bartlett.test(x[valid_indices], g), error = function(e) NULL)
    if (!is.null(tmp)) {
      res <- tibble::add_row(res,
                             Test = "Bartlett",
                             Statistic = as.numeric(tmp$statistic),
                             p.value = as.numeric(tmp$p.value))
    }
  }
  
  # Fligner检验
  if ("fligner" %in% method) {
    tmp <- tryCatch(stats::fligner.test(x[valid_indices], g), error = function(e) NULL)
    if (!is.null(tmp)) {
      res <- tibble::add_row(res,
                             Test = "Fligner",
                             Statistic = as.numeric(tmp$statistic),
                             p.value = as.numeric(tmp$p.value))
    }
  }
  
  # 返回结果（包含有效数据用于绘图）
  structure(
    list(
      df_name = df_name,
      var = var,
      group = group,
      valid_data = valid_data,  # 新增：保存有效样本数据
      res = res
    ),
    class = "homo_variance_test"
  )
}

#' @export
summary.homo_variance_test <- function(object, dec = 3, ...) {
  # 标准化说明文字（与正态性检验格式一致）
  cat("Homogeneity of variance tests\n")
  cat("Data     :", object$df_name, "\n")
  cat("Variable :", object$var, "\n")
  cat("Group    :", object$group, "\n\n")
  
  # 格式化结果表格
  result_table <- object$res %>%
    dplyr::mutate(
      Statistic = round(Statistic, dec),
      p.value = dplyr::case_when(
        p.value < 0.001 ~ "<0.001",
        is.na(p.value) ~ "",
        TRUE ~ as.character(round(p.value, dec))
      )
    )
  
  # 打印结果表格
  print(as.data.frame(result_table), row.names = FALSE)
  invisible(object)
}

#' @export
plot.homo_variance_test <- function(x, plots = c("boxplot", "density", "hist"),
                                    shiny = FALSE, custom = FALSE, ...) {
  # 1. 提取有效数据（用于绘图）
  valid_data <- x$valid_data
  if (nrow(valid_data) == 0) {
    return(ggplot2::ggplot() +
             ggplot2::annotate("text", x = 1, y = 1, label = i18n$t("No valid data for plotting")) +
             ggplot2::theme_void())
  }
  
  # 2. 定义变量名（用于图表标签）
  var_name <- x$var
  group_name <- x$group
  
  # 3. 初始化图形列表
  plot_list <- list()
  
  # 4. 生成箱线图（按分组展示数值变量分布）
  if ("boxplot" %in% plots) {
    p <- ggplot2::ggplot(valid_data,
                         ggplot2::aes(x = .data[[group_name]], 
                                      y = .data[[var_name]],
                                      fill = .data[[group_name]])) +
      ggplot2::geom_boxplot(alpha = 0.7, show.legend = FALSE) +
      ggplot2::labs(x = group_name, 
                    y = var_name, 
                    title = i18n$t("Boxplot by Group")) +
      ggplot2::theme_minimal() +
      ggplot2::theme(plot.title = ggplot2::element_text(hjust = 0.5))
    plot_list[["boxplot"]] <- p
  }
  
  # 5. 生成密度图（按分组展示数值变量分布）
  if ("density" %in% plots) {
    p <- ggplot2::ggplot(valid_data,
                         ggplot2::aes(x = .data[[var_name]],
                                      fill = .data[[group_name]],
                                      color = .data[[group_name]])) +
      ggplot2::geom_density(alpha = 0.3) +
      ggplot2::labs(x = var_name,
                    y = i18n$t("Density"),
                    title = i18n$t("Density by Group"),
                    fill = group_name,
                    color = group_name) +
      ggplot2::theme_minimal() +
      ggplot2::theme(plot.title = ggplot2::element_text(hjust = 0.5))
    plot_list[["density"]] <- p
  }
  
  # 6. 生成直方图（按分组展示数值变量分布）
  if ("hist" %in% plots) {
    p <- ggplot2::ggplot(valid_data,
                         ggplot2::aes(x = .data[[var_name]],
                                      fill = .data[[group_name]])) +
      ggplot2::geom_histogram(position = "identity", alpha = 0.5, bins = 30) +
      ggplot2::labs(x = var_name,
                    y = i18n$t("Count"),
                    title = i18n$t("Histogram by Group"),
                    fill = group_name) +
      ggplot2::theme_minimal() +
      ggplot2::theme(plot.title = ggplot2::element_text(hjust = 0.5))
    plot_list[["hist"]] <- p
  }
  
  # 7. 处理未选择图表类型的情况
  if (length(plot_list) == 0) {
    return(ggplot2::ggplot() +
             ggplot2::annotate("text", x = 1, y = 1, label = i18n$t("No plots selected")) +
             ggplot2::theme_void())
  }
  
  # 8. 组合图表（按选择顺序排列）
  combined_plot <- patchwork::wrap_plots(plot_list[plots], ncol = 1)
  
  # 9. 在Shiny中显示或返回图表
  if (shiny) {
    print(combined_plot)
    invisible(x)
  } else {
    combined_plot
  }
}
