#' Perform Sex-Phenotype Interaction Analysis for Single-Cell Data
#'
#' @description Performs differential difference analysis for a given cell type
#' to identify genes modulated by sex-phenotype interactions using limma.
#'
#' @param seurat_obj A Seurat object.
#' @param target_cell_type Character. Cell type to analyze.
#' @param sex Character. Column name for sex (default "sex").
#' @param phenotype Character. Column name for phenotype (default "status").
#' @param celltype_col Character. Column name for cell type (default "cell_type").
#' @param min_logfc Numeric. Minimum absolute log fold change for reporting significant genes (default 0.25).
#' @param alpha Numeric. FDR threshold for significance (default 0.05).
#' @param sex_labels_vector Character vector of sex labels (default c("F","M")).
#' @param phenotype_labels_vector Character vector of phenotype groups (default c("WT","TG")).
#' @param min_samples Integer. Minimum number of cells per group (default 20).
#'
#' @return A list with all DE results, filtered significant DEGs, and summary statistics.
#'
#' @importFrom Seurat DefaultAssay 
#' @importFrom SeuratObject DefaultAssay DefaultAssay<- Idents Idents<-
#' @importFrom edgeR DGEList filterByExpr calcNormFactors
#' @importFrom limma voom lmFit makeContrasts contrasts.fit eBayes topTable
#' @importFrom stats model.matrix
#' @importFrom methods slotNames
#' @export
sex_interaction_analysis_sc <- function(seurat_obj,
                                        target_cell_type,
                                        sex = "sex",
                                        phenotype = "status",
                                        celltype_col = "cell_type",
                                        min_logfc = 0.25,
                                        alpha = 0.05,
                                        sex_labels_vector = c("F", "M"),
                                        phenotype_labels_vector = c("WT", "TG"),
                                        min_samples = 20) {
  
  # --- Check cell type existence ---
  if (!(target_cell_type %in% unique(seurat_obj@meta.data[[celltype_col]]))) {
    stop(paste0("Target cell type '", target_cell_type, "' not found in metadata"))
  }
  
  # --- Subset metadata ---
  cell_meta <- seurat_obj@meta.data[
    seurat_obj@meta.data[[celltype_col]] == target_cell_type, ,
    drop = FALSE
  ]
  
  # --- Subset Seurat object ---
  cell_subset <- subset(seurat_obj, cells = rownames(cell_meta))
  
  # --- Run validation on subset (FIX) ---
  validation <- validate_input_sc(
    seurat_obj = cell_subset,
    sex = sex,
    phenotype = phenotype,
    celltype_col = celltype_col,
    sex_labels_vector = sex_labels_vector,
    phenotype_labels_vector = phenotype_labels_vector,
    min_cells = min_samples
  )
  
  # Set factors 
  cell_meta[[sex]] <- factor(cell_meta[[sex]], levels = sex_labels_vector)
  cell_meta[[phenotype]] <- factor(cell_meta[[phenotype]], levels = phenotype_labels_vector)
  
  # Create combined group
  cell_meta$Group <- factor(paste(cell_meta[[phenotype]], cell_meta[[sex]], sep="_"))
  
  assay <- cell_subset[["RNA"]]
  
  counts <- if (inherits(assay, "Assay5")) {
    # Seurat v5
    if ("counts" %in% names(assay@layers)) {
      assay@layers[["counts"]]
    } else {
      stop("No 'counts' layer found in Assay5 object.")
    }
  } else if (inherits(assay, "Assay")) {
    # Seurat v4
    assay@counts
  } else {
    stop("Unsupported assay type.")
  }
  
  counts <- as.matrix(counts)
  
  # Design matrix
  design <- model.matrix(~ 0 + Group, data = cell_meta)
  colnames(design) <- gsub("^Group", "", colnames(design))
  
  # edgeR processing 
  dge <- DGEList(counts = counts)
  keep <- filterByExpr(dge, design)
  dge <- dge[keep, , keep.lib.sizes = FALSE]
  dge <- calcNormFactors(dge, method = "TMMwsp")
  
  # voom + limma 
  vm <- voom(dge, design, plot = FALSE)
  fit <- lmFit(vm, design)
  
  # Define interaction contrast
  group_wt_f <- paste0(phenotype_labels_vector[1], "_", sex_labels_vector[1])
  group_tg_f <- paste0(phenotype_labels_vector[2], "_", sex_labels_vector[1])
  group_wt_m <- paste0(phenotype_labels_vector[1], "_", sex_labels_vector[2])
  group_tg_m <- paste0(phenotype_labels_vector[2], "_", sex_labels_vector[2])
  
  contrast_formula <- paste0(
    "(", group_tg_m, " - ", group_wt_m, ") - (",
    group_tg_f, " - ", group_wt_f, ")"
  )
  
  contrast_matrix <- makeContrasts(
    contrasts = contrast_formula,
    levels = design
  )
  
  fit2 <- contrasts.fit(fit, contrast_matrix)
  fit2 <- eBayes(fit2)
  
  # Extract results 
  res <- topTable(fit2, number = Inf, adjust.method = "BH")
  res$cell_type <- target_cell_type
  res$gene <- rownames(res)
  
  # prevent warning when checking package
  adj.P.Val <- logFC <- NULL
  sig_res <- subset(res, adj.P.Val < alpha & abs(logFC) > min_logfc)
  
  return(list(
    all_results = res,
    sig_results = sig_res,
    summary_stats = data.frame(
      cell_type = target_cell_type,
      n_total_genes = nrow(res),
      n_sig_genes = nrow(sig_res),
      stringsAsFactors = FALSE
    ),
    validation = validation
  ))
}

#' Run sex phenotype interaction analysis pipeline for single cell data
#'
#' @description Performs sex phenotype interaction analysis per cell type
#' using a limma based difference in differences model.
#'
#' @param seurat_obj Seurat object containing single cell data.
#' @param target_cell_type_flag Character. Specific cell type to analyze or "all".
#' @param sex Character. Metadata column for sex.
#' @param phenotype Character. Metadata column for phenotype.
#' @param celltype_col Character. Metadata column for cell type.
#' @param min_logfc Numeric. Minimum absolute log fold change threshold.
#' @param alpha Numeric. FDR threshold for significance.
#' @param sex_labels_vector Character vector specifying sex levels.
#' @param phenotype_labels_vector Character vector specifying phenotype levels.
#' @param min_samples Integer. Minimum number of cells per group (default 20).
#' @return A named list containing interaction analysis results per cell type.
#'
#' @export

sex_interaction_pipeline_sc <- function(seurat_obj,
                                        target_cell_type_flag = "all",
                                        sex = "sex",
                                        phenotype = "status",
                                        celltype_col = "cell_type",
                                        min_logfc = 0.25,
                                        alpha = 0.05,
                                        sex_labels_vector = c("F", "M"),
                                        phenotype_labels_vector = c("WT", "TG"),
                                        min_samples = 20) {
  
  results <- list()
  

  # Determine cell types to analyze
  if ("all" %in% target_cell_type_flag) {
    
    cell_types <- unique(seurat_obj@meta.data[[celltype_col]])
    
  } else {
    
    available_ct <- unique(seurat_obj@meta.data[[celltype_col]])
    missing_ct <- setdiff(target_cell_type_flag, available_ct)
    
    if (length(missing_ct) > 0) {
      stop(paste(
        "Cell type(s) not found:",
        paste(missing_ct, collapse = ", ")
      ))
    }
    
    cell_types <- target_cell_type_flag
  }
  
  # Run analysis per cell type
  for (cell in cell_types) {
    
    message("Running analysis for cell type: ", cell)
    
    results[[cell]] <- sex_interaction_analysis_sc(
      seurat_obj = seurat_obj,
      target_cell_type = cell,
      sex = sex,
      phenotype = phenotype,
      celltype_col = celltype_col,
      min_logfc = min_logfc,
      alpha = alpha,
      sex_labels_vector = sex_labels_vector,
      phenotype_labels_vector = phenotype_labels_vector,
      min_samples = min_samples
    )
  }
  
  return(results)
}
  
  
  