# app.R
library(shiny)
library(ComplexHeatmap)
library(InteractiveComplexHeatmap)
library(circlize)
library(ggplot2)
library(dplyr)
library(tidyr)
library(stringr)
library(RColorBrewer)
library(ragg)

# CARD heatmap 생성 함수
create_card_heatmap <- function(input_csv, metadata_file, meta_col_selected) {

    args <- commandArgs(trailingOnly = TRUE)

    if (length(args) == 0) {
        cat("No arguments provided. Exiting script.\n -i : Input is rgi result generated by add_rgi_togenePA.py, -m metadata CSV file, -out output heatmap file, -meta_cols : metadata column numbers like 2,3,4\n")
    quit(save = "no", status = 1)
    }

    arg_list <- list()
    for (i in seq(1, length(args), 2)) {
    arg_list[[args[i]]] <- args[i + 1]
    }

    input_csv <- arg_list[["-i"]]
    metadata_file <- arg_list[["-m"]]
    output_file <- arg_list[["-out"]]
    meta_col_selected <- arg_list[["-mc"]]
    meta_col_selected <- as.integer(meta_col_selected)
    meta_cols <- NULL

    output_html <- arg_list[["-out_html"]]

    set_font <- function() {
    par(family = "Courier")
    }

    set_font()

    if ("-meta_cols" %in% names(arg_list)) {
        meta_cols <- unlist(strsplit(arg_list[["-meta_cols"]], ","))
    }

    # prohibit too long legend text. 
    wrap_after_two_semicolons <- function(s) {
    parts <- unlist(strsplit(s, split = ";", fixed = TRUE))
    new_text <- ""
    for (i in seq_along(parts)) {
        new_text <- paste(new_text, parts[i], sep = "")
        if (i < length(parts) && (i %% 2 == 0)) {
        new_text <- paste(new_text, ";", "\n", sep = "")
        } else if (i < length(parts)) {
        new_text <- paste(new_text, ";", sep = "")
        }
    }
    new_text
    }

    wrap_after_semicolon <- function(s) {
    parts <- unlist(strsplit(s, split = ";", fixed = TRUE))
    new_text <- paste(parts, collapse = ";\n")
    new_text
    }

    clean_column_names <- function(df) {
    names(df) <- gsub(" ", "_", names(df))
    return(df)
    }

    card_raw <- read.csv(input_csv, header = TRUE,check.names=FALSE)

    card_raw <- clean_column_names(card_raw)

    #input should be csv. 
    metadata <- read.csv(metadata_file, header = TRUE, check.names = FALSE)

    selected_colname = colnames(metadata)[meta_col_selected]

    data <- read.csv(input_csv, header = TRUE, check.names = FALSE)
    if (!is.null(meta_cols)) {
        meta_cols <- as.numeric(meta_cols)
        metadata <- metadata[, meta_cols, drop = FALSE]
    }

    rownames(metadata) <- metadata[,1] # should revise automated metadata  
    # free below line 
    # rownames(metadata) <- metadata[,colnaems(metadata[,])]


    card_heatmap_data <- card_raw[, 2:(ncol(card_raw) - 3)]


    selected_columns <- c("Completeness", "Contamination", "classification", colnames(metadata[selected_colname])) #meta1380 %>% select(ncol(.)))
    meta_filtered_forvis <- metadata[, selected_columns]
    meta_filtered_forvis <- meta_filtered_forvis %>%
    mutate(!!selected_colname := replace(.[[selected_colname]], .[[selected_colname]] == "", "NA"))

    classification_split <- strsplit(as.character(meta_filtered_forvis$classification), ";")
    classification_df <- do.call(rbind, classification_split)
    colnames(classification_df) <- c("Domain", "Phylum", "Class", "Order", "Family", "Genus", "Species")
    classification_df <- as.data.frame(classification_df)
    meta_filtered_forvis <- cbind(meta_filtered_forvis[, -which(colnames(meta_filtered_forvis) == "classification")], classification_df)

    meta_filtered_forvis_ordered <- meta_filtered_forvis[match(colnames(card_heatmap_data), rownames(meta_filtered_forvis)),]

    top_annotation <- HeatmapAnnotation(df = meta_filtered_forvis_ordered,
                                        annotation_name_gp = gpar(fontsize = 7))


    basic_metadata <- meta_filtered_forvis_ordered[, !colnames(meta_filtered_forvis_ordered) %in% c(selected_colname,"Domain", "Phylum", "Class", "Order", "Family")]
    user_metadata <- meta_filtered_forvis_ordered[, selected_colname, drop = FALSE]

    top_annotation_boxplot <- HeatmapAnnotation(Average_value = anno_boxplot(as.matrix(card_heatmap_data), axis = TRUE,height = unit(1.0, "cm"),
                                axis_param = list(labels_rot = 0)),
    annotation_name_side = "left", annotation_name_rot = 0,
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier",fontface="bold")#,
    #height = unit(1.0, "cm")
    )
    top_annotation_basic <- HeatmapAnnotation(
    df = basic_metadata,
    annotation_name_side = "left",
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier",fontface="bold"),
    annotation_legend_param = list(
    title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
    labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )
    top_annotation_user <- HeatmapAnnotation(
    df = user_metadata,
    annotation_name_side = "left",
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", col = "red", fontface="bold"),
        annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )

    pdf_width <- (2.5*ncol(card_heatmap_data) +90 + 110 +100 +40) / 25.4
    pdf_height <- (2.5*nrow(card_heatmap_data) + 45 +40 + 40 ) / 25.4

    if (pdf_width >= 20.9) {
    pdf_width <- 20.9
    }

    if (pdf_height >= 15) {
    pdf_height <- 15.65
    }

    arg_info <- card_raw[, (ncol(card_raw) - 2):ncol(card_raw)]


    rowsum_data <- data.frame(rowsum = rowSums(card_heatmap_data))

    # ############
    # reorder based on largest category
    integrated_data <- cbind(card_heatmap_data, arg_info) %>%
    mutate(rowsum = rowSums(select(., 1:(ncol(card_heatmap_data)))))

    integrated_data_sorted <- integrated_data %>%
    group_by(Resistance_Mechanism) %>%
    arrange(Resistance_Mechanism, desc(rowsum)) %>%
    mutate(row_index = row_number()) %>%
    ungroup() %>%
    arrange(Resistance_Mechanism, row_index)

    row_order <- integrated_data_sorted$row_index

    if(n_distinct(integrated_data_sorted$CARD_Short_Name) > 90) {
    top_90_card <- integrated_data_sorted %>%
        group_by(CARD_Short_Name) %>%
        summarise(total_rowsum = sum(rowsum)) %>%
        arrange(desc(total_rowsum)) %>%
        slice_head(n = 90) %>%
        pull(CARD_Short_Name)
    
    integrated_data_sorted <- integrated_data_sorted %>%
        mutate(CARD_Short_Name_display = ifelse(CARD_Short_Name %in% top_90_card, CARD_Short_Name, "Other"))
    } else {
    integrated_data_sorted$CARD_Short_Name_display <- integrated_data_sorted$CARD_Short_Name
    }


    integrated_matrix <- as.matrix(integrated_data_sorted[, 1:ncol(card_heatmap_data)])

    split_data <- split(as.data.frame(t(integrated_matrix)), meta_filtered_forvis_ordered[, selected_colname])
    split_matrix <- do.call(cbind, lapply(split_data, function(x) colMeans(x, na.rm = TRUE)))

    print(paste("Dimensions of card_heatmap_data:", paste(dim(card_heatmap_data), collapse = " x ")))
    print(paste("Dimensions of split_matrix:", paste(dim(split_matrix), collapse = " x ")))

    distribution_colors <- scales::hue_pal()(ncol(split_matrix))
    distribution_legend <- Legend(
        labels = colnames(split_matrix),
        legend_gp = gpar(fill = distribution_colors),
        title = "Resistance_averages",
        title_gp = gpar(fontsize = 12, fontfamily = "Courier",fontface="bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")    
    )

    left_annotation <- rowAnnotation(
    Resistance_averages = anno_points(
        split_matrix,
        pch = 1:ncol(split_matrix),
        size = unit(1, "mm"),
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        gp = gpar(col = scales::hue_pal()(ncol(split_matrix))),
        width = unit(3, "cm")
    ),
    annotation_name_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold")
    )


    integrated_data_sorted$Resistance_Mechanism <- sapply(integrated_data_sorted$Resistance_Mechanism, wrap_after_semicolon)

    #arg_info$"Drug_Class" <- sapply(arg_info$"Drug_Class", wrap_after_two_semicolons)

    head(integrated_data)


    row_annotation <- HeatmapAnnotation(
    Resistance_Mechanism = integrated_data_sorted$Resistance_Mechanism,
    CARD_Short_Name = integrated_data_sorted$CARD_Short_Name_display,
    which = 'row',
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", fontface = "bold"),
    annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )

    row_annotation_hover <- HeatmapAnnotation(
    Drug_Class = integrated_data_sorted$Drug_Class,
    show_annotation_name = TRUE,
    show_legend = FALSE,
    which = 'row'
    )

    message("which")
    head(row_annotation)

    length(unique(as.vector(card_heatmap_data)))


    process_card_heatmap_data <- function(card_heatmap_data) {
    if (all(card_heatmap_data %in% c(0, 1))) {
        # Presence/Absence case
        return(list(
        color_function = colorRamp2(c(0, 1), c("lightgrey", "red")),
        legend_labels = c("Absent", "Present"),
        at = c(0, 1)
        ))
    } else {
        # Gene count case
        breaks <- c(0, min(card_heatmap_data[card_heatmap_data > 0]), max(card_heatmap_data))
        colors <- c("lightgrey", "white", "red")
        return(list(
        color_function = colorRamp2(breaks, colors),
        legend_labels = as.character(breaks),
        at = breaks
        ))
    }
    }

    print(card_heatmap_data[1:3,1:3])
    print(card_heatmap_data[(nrow(card_heatmap_data)-3):nrow(card_heatmap_data),(ncol(card_heatmap_data)-3):ncol(card_heatmap_data)])

    result <- process_card_heatmap_data(card_heatmap_data)
    my_color_function <- result$color_function
    legend_labels <- result$legend_labels
    legend_at <- result$at


    ht1 <- Heatmap(
        as.matrix(integrated_data_sorted[, 1:ncol(card_heatmap_data)]),
        #as.matrix(card_heatmap_data),
        name = "Antimicrobial resistance\n gene number",
        col = my_color_function,

        top_annotation = c(top_annotation_boxplot, top_annotation_basic, top_annotation_user),
        right_annotation = c(row_annotation, row_annotation_hover),
        #row_order = order(as.integer(factor(grouped_data$Resistance_Mechanism)), grouped_data$row_index),
        row_order = order(as.integer(factor(integrated_data_sorted$Resistance_Mechanism)), integrated_data_sorted$row_index),
        left_annotation=left_annotation,
        heatmap_legend_param = list(
        legend_direction = "horizontal",
        title_gp = gpar(fontsize = 12, fontfamily = "Courier",fontface="bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier"),
        labels = legend_labels,
        at = legend_at
        ), 
        show_row_names = FALSE,
        show_column_names = FALSE,
        show_column_dend = FALSE,
        show_row_dend = FALSE,
        column_split  = meta_filtered_forvis_ordered[,selected_colname],
        row_names_gp = gpar(fontsize = 11, fontfamily = "Courier"),
        column_names_gp = gpar(fontsize = 11, fontfamily = "Courier"),
        column_title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold", col = "blue")
    )

    ht1 <- draw(ht1,
    padding = unit(c(2, 2, 2, 2), "cm"),
    annotation_legend_list = list(distribution_legend),annotation_legend_side = "left")

    # output_file <- "heatmap_CARD.pdf"
    # pdf(file = output_file, width = pdf_width, height = pdf_height)
    # #pdf(file = output_file, width = 20, height = 15)
    # draw(ht1)
    # dev.off()
    return(ht1)
    #htShiny(ht1, output_ui_float = TRUE, save = output_html)
   
}

# dbCAN heatmap 생성 함수
# dbCAN heatmap 생성 함수
create_dbcan_heatmap <- function(input_csv, metadata_file, meta_col_selected) {
    args <- commandArgs(trailingOnly = TRUE)

    set_font <- function() {
    par(family = "Courier")
    }
    set_font()

    if (length(args) == 0) {
        cat("No arguments provided. Exiting script.\n -i : Input is dbcan result file. -m metadata CSV file, -out output heatmap file, -meta_cols : metadata column numbers like 2,3,4\n")
    quit(save = "no", status = 1)
    }

    arg_list <- list()
    for (i in seq(1, length(args), 2)) {
    arg_list[[args[i]]] <- args[i + 1]
    }

    input_csv <- arg_list[["-i"]]
    metadata_file <- arg_list[["-m"]]
    output_file <- arg_list[["-out"]]
    meta_col_selected <- arg_list[["-mc"]]
    meta_col_selected <- as.integer(meta_col_selected)
    meta_cols <- NULL

    output_html <- arg_list[["-out_html"]]

    if ("-meta_cols" %in% names(arg_list)) {
        meta_cols <- unlist(strsplit(arg_list[["-meta_cols"]], ","))
    }

    # prohibit too long legend text. 
    wrap_after_two_semicolons <- function(s) {
    parts <- unlist(strsplit(s, split = ";", fixed = TRUE))
    new_text <- ""
    for (i in seq_along(parts)) {
        new_text <- paste(new_text, parts[i], sep = "")
        if (i < length(parts) && (i %% 2 == 0)) {
        new_text <- paste(new_text, ";", "\n", sep = "")
        } else if (i < length(parts)) {
        new_text <- paste(new_text, ";", sep = "")
        }
    }
    new_text
    }

    clean_column_names <- function(df) {
    names(df) <- gsub(" ", "_", names(df))
    return(df)
    }

    dbcan_raw <- read.csv(input_csv, header = TRUE,check.names=FALSE)
    dbcan_raw<- clean_column_names(dbcan_raw)

    #input should be csv. 
    metadata <- read.csv(metadata_file, header = TRUE, check.names = FALSE)
    selected_colname = colnames(metadata)[meta_col_selected]

    data <- read.csv(input_csv, header = TRUE, check.names = FALSE)
    if (!is.null(meta_cols)) {
        meta_cols <- as.numeric(meta_cols)
        metadata <- metadata[, meta_cols, drop = FALSE]
    }

    rownames(metadata) <- metadata[,1] # should revise automated metadata  

    sort_labels <- function(df, label_col) {
    df %>%
        mutate(
        Prefix = str_extract(!!sym(label_col), "^[A-Z]+"),
        Number = as.numeric(str_extract(!!sym(label_col), "[0-9]+$")),
        Prefix_Order = match(Prefix, c("AA", "CBM", "CE", "GH", "GT", "PL")) # Set custom order of prefixes
        ) %>%
        arrange(Prefix_Order, Number) %>%
        select(-c(Prefix, Number, Prefix_Order))
    }

    dbcan_raw <- sort_labels(dbcan_raw,"HMMER")

    head(dbcan_raw)
    dbcan_raw <- dbcan_raw %>% 
    mutate(Prefix = str_extract(!!sym("HMMER"), "^[A-Z]+"))
    dbcan_heatmap_data<- dbcan_raw[,2:(ncol(dbcan_raw)-1)]

    selected_columns <- c("Completeness", "Contamination", "classification", colnames(metadata[selected_colname])) #meta1380 %>% select(ncol(.)))
    meta_filtered_forvis <- metadata[, selected_columns]
    meta_filtered_forvis <- meta_filtered_forvis %>%
    mutate(!!selected_colname := replace(.[[selected_colname]], .[[selected_colname]] == "", "NA"))

    classification_split <- strsplit(as.character(meta_filtered_forvis$classification), ";")
    classification_df <- do.call(rbind, classification_split)
    colnames(classification_df) <- c("Domain", "Phylum", "Class", "Order", "Family", "Genus", "Species")
    classification_df <- as.data.frame(classification_df)
    meta_filtered_forvis <- cbind(meta_filtered_forvis[, -which(colnames(meta_filtered_forvis) == "classification")], classification_df)

    meta_filtered_forvis_ordered <- meta_filtered_forvis[match(colnames(dbcan_heatmap_data), rownames(meta_filtered_forvis)),]

    # top_annotation <- HeatmapAnnotation(df = meta_filtered_forvis_ordered,
    #                                     annotation_name_gp = gpar(fontsize = 7))

    basic_metadata <- meta_filtered_forvis_ordered[, !colnames(meta_filtered_forvis_ordered) %in% c(selected_colname,"Domain", "Phylum", "Class", "Order", "Family")]
    user_metadata <- meta_filtered_forvis_ordered[, selected_colname, drop = FALSE]

    top_annotation_boxplot <- HeatmapAnnotation(Average_value = anno_boxplot(as.matrix(dbcan_heatmap_data), axis = TRUE, height = unit(1.0, "cm"),
                                axis_param = list(labels_rot = 0)),
    annotation_name_side = "left", annotation_name_rot = 0,
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", fontface="bold")
    )

    top_annotation_basic <- HeatmapAnnotation(
    df = basic_metadata,
    annotation_name_side = "left",
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", fontface="bold"),
    annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )

    top_annotation_user <- HeatmapAnnotation(
    df = user_metadata,
    annotation_name_side = "left",
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", col = "red", fontface="bold"),
    annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )

    integrated_data <- cbind(dbcan_heatmap_data, dbcan_raw[, c("Prefix", "HMMER")]) %>%

    mutate(rowsum = rowSums(select(., 1:(ncol(dbcan_heatmap_data)))))

    integrated_data_sorted <- integrated_data %>%
    group_by(Prefix) %>%
    arrange(Prefix, desc(rowsum)) %>%
    mutate(row_index = row_number()) %>%
    ungroup() %>%
    arrange(Prefix, row_index)

    row_order <- order(integrated_data_sorted$Prefix, integrated_data_sorted$row_index)

    #row_order <- integrated_data_sorted$row_index
    split_data <- split(as.data.frame(t(integrated_data_sorted[, 1:ncol(dbcan_heatmap_data)])), meta_filtered_forvis_ordered[, selected_colname])
    split_matrix <- do.call(cbind, lapply(split_data, function(x) colMeans(x, na.rm = TRUE)))

    distribution_colors <- scales::hue_pal()(ncol(split_matrix))
    distribution_legend <- Legend(
        labels = colnames(split_matrix),
        legend_gp = gpar(fill = distribution_colors),
        title = "CAZyme_averages",
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface="bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")    
    )

    left_annotation <- rowAnnotation(
    CAZyme_averages = anno_points(
        split_matrix,
        pch = 1:ncol(split_matrix),
        size = unit(1, "mm"),
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        gp = gpar(col = scales::hue_pal()(ncol(split_matrix))),
        width = unit(3, "cm")
    ),
    annotation_name_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold")
    )

    caz_info <- integrated_data_sorted[, c("Prefix", "HMMER")]
    names(caz_info) <- c("CAZymes family", "CAZymes subfamily")

    row_annotation <- HeatmapAnnotation(df = caz_info, which='row',
                                                                        show_legend = c("CAZymes family" = TRUE, "CAZymes subfamily" = FALSE),
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", fontface = "bold"),
    annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )
    message("which")
    head(row_annotation)

    length(unique(as.vector(dbcan_heatmap_data)))

    breaks <- c(0, min(dbcan_heatmap_data[dbcan_heatmap_data>0]), max(dbcan_heatmap_data))
    colors <- c("lightgrey", "white", "#22d62b")

    if (length(unique(as.vector(dbcan_heatmap_data))) == 1) {
    my_color_function <- "#22d62b"
    } else {
    my_color_function <- colorRamp2(breaks,colors)
    }

    ht1 <- Heatmap(
        as.matrix(integrated_data_sorted[, 1:ncol(dbcan_heatmap_data)]),
        name = "Carbohydrate-active enzymes",
        col = my_color_function,
        top_annotation = c(top_annotation_boxplot, top_annotation_basic, top_annotation_user),
        right_annotation = row_annotation,
        left_annotation = left_annotation,
        show_row_names = FALSE,
        show_column_names = FALSE,
        show_column_dend = FALSE,
        show_row_dend = FALSE,
        cluster_rows = FALSE,
        column_split  = meta_filtered_forvis_ordered[,selected_colname],
        heatmap_legend_param = list(
            legend_direction = "horizontal",
            title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface="bold"),
            labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
        ),
        row_names_gp = gpar(fontsize = 11, fontfamily = "Courier"),
        column_names_gp = gpar(fontsize = 11, fontfamily = "Courier"),
        column_title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold", col = "blue")
    )

    pdf_width <- (2.5*ncol(dbcan_heatmap_data) + 90 + 110 + 40) / 25.4
    pdf_height <- (2.5*nrow(dbcan_heatmap_data) + 45 + 40 + 40) / 25.4
    if (pdf_width >= 20.9) {
    pdf_width = 20.9
    }


    if (pdf_height >= 15) {
    pdf_height = 15.65
    }

    output_file <- "heatmap_dbCAN.pdf"
    ht1 <- draw(ht1,
    padding = unit(c(2, 2, 2, 2), "cm"),
    annotation_legend_list = list(distribution_legend),
    annotation_legend_side = "left"
    )
# pdf(file = output_file, width = pdf_width, height = pdf_height)
# draw(ht, padding = unit(c(2, 2, 2, 2), "cm"), annotation_legend_list = list(distribution_legend), annotation_legend_side = "left")
# #pdf(file = output_file)

# dev.off()

#    htShiny(ht, output_ui_float = TRUE, save = output_html)
    return(ht1)
}

# KEGG heatmap 생성 함수
# KEGG heatmap 생성 함수
create_kegg_heatmap <- function(input_kegg_matrix, metadata_file, meta_col_selected, module_completeness_threshold) {
    library(ComplexHeatmap)
    library(circlize)
    library(ggplot2)
    library(dplyr)
    library(tidyr)
    library(stringr)
    library(RColorBrewer)
    library(circlize)
    library(InteractiveComplexHeatmap)
    library(shiny)
    library(DT)
    library(htmlwidgets)
    #  parse command line arguments
    args <- commandArgs(trailingOnly = TRUE)

    set_font <- function() {
    par(family = "Courier")
    }

    set_font()

    if (length(args) == 0) {
    # Handle the case where no arguments are passed
    #    Set default values or exit with a message
        cat("No arguments provided. Exiting script.\n -i : KO.csv matrix, -m metadata.csv -out_html shinyout -out_table module_table.tsv,  \n -mc : module completeness - optional  \n -meta_cols : column number like 2,3,4   ")
        quit(save = "no", status = 1)
        }

    arg_list <- list()
    for (i in seq(1, length(args), 2)) {
    arg_list[[args[i]]] <- args[i + 1]
    }

    # Assign arguments to variables
    input_kegg_matrix <- arg_list[["-i"]]
    # metadata <- arg_list[["-m"]]
    output_html <- arg_list[["-out_html"]]
    output_table <- arg_list[["-out_table"]]
    metadata_file <- arg_list[["-m"]]

    meta_col_selected <- arg_list[["-n"]]
    meta_col_selected <- as.integer(meta_col_selected)
    meta_cols <- NULL


    #metadata_provided <- "-m" %in% names(arg_list)
    #metadata <- NULL
    #meta_cols <- NULL
    # if ("-meta_cols" %in% names(arg_list)) {
    #     meta_cols <- unlist(strsplit(arg_list[["-meta_cols"]], ","))
    # }
    metadata <- read.csv(metadata_file, header = TRUE, check.names = FALSE)
    # default KEGG module threshold is 50%. 
    module_completeness_threshold <- 0.5

    selected_colname = colnames(metadata)[meta_col_selected]

    if ("-mc" %in% names(arg_list)) {
    mc_value <- as.numeric(arg_list[["-mc"]])
    if (!is.na(mc_value) && mc_value >= 0 && mc_value <= 1) {
        module_completeness_threshold <- mc_value
    } else {
        warning("Invalid module completeness threshold provided. Using default value of 0.5 that is 50%.")
    }
    }

    library(ggkegg)
    library(ggfx)
    library(tidygraph)
    library(dplyr)
    library(tidyr)
    library(parallel)

    # Read the input files

    KOtable <- read.csv(input_kegg_matrix, header = TRUE,check.names =FALSE)
    KOtable <- KOtable[,-1]


    ko_long_format <-  KOtable %>%
    pivot_longer(cols = everything(), names_to = "Genome", values_to = "KOs")
    unique(ko_long_format$Genome)


    mapper <- data.table::fread("/opt/database/kofam/mapper.tsv", header=TRUE)
    allmods <-  gsub("md:", "", mapper$V1) %>%  unique()


    # modules downloaded in 2023 Dec 20 
    mf <-  list.files("/opt/database/KEGG_modules")
    mf <- mf[startsWith(mf, "M")]
    annos <- list()

    library(parallel)
    cl <-  makeCluster(32)
    clusterEvalQ(cl, {
    library(ggkegg)
    library(ggfx)
    library(tidygraph)
    library(dplyr)
    library(tidyr)
    })
    calculate_completeness <-  function(genome) {
    kos <- KOtable[[genome]][!is.na(KOtable[[genome]])]
    mcs <- sapply(mf, function(mod) {
        mc <- module_completeness(module(mod, directory="/opt/database/KEGG_modules/"), 
                                query = kos)
        mean(mc$complete)
    })
    names(mcs) <- mf
    return(mcs)
    }
    clusterExport(cl, c("KOtable", "mf", "calculate_completeness")) 
    results <- parLapply(cl, colnames(KOtable), calculate_completeness)
    names(results) <- colnames(KOtable)
    stopCluster(cl)

    hdf <- data.frame(results,check.names=FALSE)

    row.names(hdf) <- mf
    hdf[is.na(hdf)] <- 0
    threshold <- 0.5
    hdf <- hdf[apply(hdf, 1, function(x) any(x >= module_completeness_threshold)), ]

    # module description and CLASS description third columns are most bigger concept 
    #moddesc <- data.table::fread("https://rest.kegg.jp/list/module", header=FALSE)
    #data.table::fwrite(module_desc,"module_desc.txt",col.names=TRUE)
    moddesc<- data.table::fread("/opt/database/kofam/module_desc.txt", header=FALSE)

    mod_class <- read.csv("/opt/database/KEGG_modules/modes_class_description.tsv",
            sep='\t',header=FALSE)
    #mod_class_name <- read.csv("/opt/database/KEGG_modules/modes_class_Name_description.tsv",
    #         sep='\t',header=FALSE)


    merged_modedesc <- merge(moddesc, mod_class, by="V1")

    library(ragg)
    library(ComplexHeatmap)
    library(circlize)
    library(InteractiveComplexHeatmap)
    rownames(hdf)

    #generate ordered module table following CLASS
    merged_modedesc <- merged_modedesc %>%
    arrange(V2.y, V3, V2.x)
    module_order <- merged_modedesc$V1[merged_modedesc$V1 %in% rownames(hdf)]
    hdf <- hdf[module_order, ]
    annotation_reordered_modedesc <- merged_modedesc %>%
    filter(V1 %in% rownames(hdf)) %>%
    select(V2.x, V3,V2.y)


    library(tibble)
    ## new add, order 
    hdf <- hdf %>%
    rownames_to_column("Module") %>%
    left_join(merged_modedesc, by = c("Module" = "V1")) %>%
    mutate(rowsum = rowSums(select(., where(is.numeric)))) %>%
    group_by(V2.y) %>%
    arrange(V2.y, desc(rowsum)) %>%
    ungroup() %>%
    column_to_rownames("Module") %>%
    select(-rowsum, -V2.x, -V3, -V2.y)


    annotation_reordered_modedesc <- merged_modedesc %>%
    filter(V1 %in% rownames(hdf)) %>%
    mutate(rowsum = rowSums(select(hdf, where(is.numeric)))) %>%
    arrange(V2.y, desc(rowsum)) %>%
    select(V2.x, V3, V2.y)

    names(annotation_reordered_modedesc) <- c("Module_Name", "Pathway_Category", "Pathway_Class")

    ha_module <- rowAnnotation(df = annotation_reordered_modedesc[, c("Pathway_Category", "Pathway_Class")],
                            gp = gpar(fontsize = 11, fontfamily = "Courier"),  
                            annotation_name_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
                            annotation_legend_param = list(
                                title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
                                labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
                            )
    )

    rownames(metadata) <- metadata[,1]
    selected_columns <- c("Completeness", "Contamination", "classification", colnames(metadata[selected_colname]))
    meta_filtered_forvis <- metadata[, selected_columns]
    head(meta_filtered_forvis)
    meta_filtered_forvis <- meta_filtered_forvis %>%
    mutate(!!selected_colname := replace(.[[selected_colname]], .[[selected_colname]] == "", "NA"))

    classification_split <- strsplit(as.character(meta_filtered_forvis$classification), ";")
    classification_df <- do.call(rbind, classification_split)
    colnames(classification_df) <- c("Domain", "Phylum", "Class", "Order", "Family", "Genus", "Species")
    classification_df <- as.data.frame(classification_df)
    meta_filtered_forvis <- cbind(meta_filtered_forvis[, -which(colnames(meta_filtered_forvis) == "classification")], classification_df)
    meta_filtered_forvis_ordered <- meta_filtered_forvis[match(colnames(hdf), rownames(meta_filtered_forvis)),]


    #split selected one and basic metadata
    basic_metadata <- meta_filtered_forvis_ordered[, !colnames(meta_filtered_forvis_ordered) %in% c(selected_colname,"Domain", "Phylum", "Class", "Order", "Family")]
    user_metadata <- meta_filtered_forvis_ordered[, selected_colname, drop = FALSE]

    top_annotation_boxplot <- HeatmapAnnotation(Average_value = anno_boxplot(as.matrix(hdf), axis = TRUE,height = unit(1.0, "cm"),
                                axis_param = list(labels_rot = 0)),
    annotation_name_side = "left", annotation_name_rot = 0,
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier",fontface="bold")#,
    #height = unit(1.0, "cm")

    )

    top_annotation_basic <- HeatmapAnnotation(
    df = basic_metadata,
    annotation_name_side = "left",
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier",fontface="bold"),
    annotation_legend_param = list(
    title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
    labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    ))


    top_annotation_user <- HeatmapAnnotation(
    df = user_metadata,
    annotation_name_side = "left",
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", col = "red", fontface="bold"),
        annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )

    split_data <- split(as.data.frame(t(hdf)), meta_filtered_forvis_ordered[, selected_colname])
    split_matrix <- do.call(cbind, lapply(split_data, function(x) colMeans(x, na.rm = TRUE)))

    print(paste("Dimensions of hdf:", paste(dim(hdf), collapse = " x ")))
    print(paste("Dimensions of split_matrix:", paste(dim(split_matrix), collapse = " x ")))

    distribution_colors <- scales::hue_pal()(ncol(split_matrix))
    distribution_legend <- Legend(
        labels = colnames(split_matrix),
        legend_gp = gpar(fill = distribution_colors),
        title = "Module_averages",
        title_gp = gpar(fontsize = 12, fontfamily = "Courier",fontface="bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")    
    )

    print(paste("Number of groups after split:", length(split_data)))
    print(paste("Dimensions of split_matrix:", paste(dim(split_matrix), collapse = " x ")))
    print(paste("Dimensions of hdf:", paste(dim(hdf), collapse = " x ")))
    #head(hdf)
    #print(split_matrix)


    if (nrow(split_matrix) != nrow(hdf)) {
    stop("Mismatch in dimensions between split_matrix and hdf.")
    }

    # left annotation , average module value in each  group of genomes 
    left_annotation <- rowAnnotation(
    Module_averages = anno_points(split_matrix, 
                                pch = 1:ncol(split_matrix),
                                size = unit(1, "mm"),
                                title_gp = gpar(fontsize = 12, fontfamily = "Courier",fontface="bold"),

                                gp = gpar(col = scales::hue_pal()(ncol(split_matrix))),
                                width = unit(3, "cm")
    ),  annotation_name_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface="bold")
    )


    col_fun <- colorRamp2(c(0, module_completeness_threshold -0.0000001 ,module_completeness_threshold, 1), c("black","black", "white", scales::muted("red")))
    head(hdf)

    margin <- 20 
    # margin *2 + bottom top , marig*2 + left right
    pdf_width <- (2.5*ncol(hdf) +90 + 110 +  40) / 25.4
    pdf_height <- (2.5*nrow(hdf) + 45 +40 + 40 ) / 25.4

    # set maximum length
    if (pdf_width >= 20.9) {
    pdf_width = 20.9
    }
    if (pdf_height >= 15) {
    pdf_height = 15.65
    }

    #width = unit(4, "cm")

    ht1 <- Heatmap(as.matrix(hdf), show_column_names = FALSE,
                col = col_fun,
                right_annotation = ha_module,
                left_annotation=left_annotation,
    #               top_annotation = top_annotation,
                top_annotation = c(top_annotation_boxplot,top_annotation_basic, top_annotation_user),
                show_column_dend = FALSE,
                cluster_rows = FALSE,
                heatmap_legend_param = list(
                    legend_direction = "horizontal",
                    title_gp = gpar(fontsize = 12, fontfamily = "Courier",fontface="bold"),
                    labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
                    ), 
                    name = "Module completeness",
                    border = TRUE,
                    column_split  = meta_filtered_forvis_ordered[,selected_colname],
                    row_names_gp = gpar(fontsize = 11, fontfamily = "Courier"),
                    column_names_gp = gpar(fontsize = 11, fontfamily = "Courier"),
                column_title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold", col = "blue"),  #set font of row title (metadata )

    ht1 <- draw(ht1,
    padding = unit(c(2, 2, 2, 2), "cm"),
    annotation_legend_list = list(distribution_legend),annotation_legend_side = "left")
    return(ht1)

    #draw(lgd, x = unit(1, "cm"), y = unit(1, "cm"), just = c("left", "bottom"))

    # output_file <- "heatmap_KEGG.pdf"
    # pdf(file = output_file, width = pdf_width, height = pdf_height)
    # #pdf(file = output_file, width = 20, height = 15)
    # draw(ht1)
    # dev.off()

    # Save the interactive plot
    # hover_info <- data.frame(
    # Module = rownames(hdf),
    # Name = annotation_reordered_modedesc$Module_Name,
    # Category = annotation_reordered_modedesc$Pathway_Category,
    # Class = annotation_reordered_modedesc$Pathway_Class
    # )

######################################################

######################################################
# htShiny기존 코드 . 
#htShiny(ht1, output_ui_float = TRUE, save = output_html)
# Save the module completeness table
#write.csv(hdf, file = output_table)
}

# VFDB heatmap 생성 함수
create_vfdb_heatmap <- function(input_csv, metadata_file, meta_col_selected) {
    library(ComplexHeatmap)
    library(circlize)
    library(ggplot2)
    library(dplyr)
    library(tidyr)
    library(stringr)
    library(RColorBrewer)

    set_font <- function() {
    par(family = "Courier")
    }
    set_font()

    args <- commandArgs(trailingOnly = TRUE)

    if (length(args) == 0) {
        cat("No arguments provided. Exiting script.\n -i : Input is CARD csv result generated by add_rgi_togenePA.py, -m metadata CSV file, -out output heatmap file, -meta_cols : metadata column numbers like 2,3,4\n")
    quit(save = "no", status = 1)
    }
    arg_list <- list()
    for (i in seq(1, length(args), 2)) {
    arg_list[[args[i]]] <- args[i + 1]
    }

    input_csv <- arg_list[["-i"]]
    metadata_file <- arg_list[["-m"]]
    output_file <- arg_list[["-out"]]
    meta_col_selected <- arg_list[["-mc"]]
    meta_col_selected <- as.integer(meta_col_selected)
    meta_cols <- NULL
    output_html <- arg_list[["-out_html"]]

    if ("-meta_cols" %in% names(arg_list)) {
        meta_cols <- unlist(strsplit(arg_list[["-meta_cols"]], ","))
    }


    vfdb_raw <- read.csv(input_csv, header = TRUE, check.names = FALSE)
    metadata <- read.csv(metadata_file, header = TRUE, check.names = FALSE)
    selected_colname = colnames(metadata)[meta_col_selected]
    print(selected_colname)
    if (ncol(vfdb_raw) - 7 != nrow(metadata)) {
        stop("Mismatch in the number of columns in heatmap data and the number of rows in metadata.")
    }
    # for visualization partitioning
    # group_col_name <- colnames(metadata_file)[as.integer(meta_col_selected)]
    heatmap_data <- vfdb_raw[, 2:(ncol(vfdb_raw) - 6)]

    vf_info <- vfdb_raw[, (ncol(vfdb_raw) - 5):ncol(vfdb_raw)] # last 6 fields

    heatmap_data_summarized <- heatmap_data %>% 
    mutate(VFID = vf_info$VF_ID) %>%
    group_by(VFID) %>%
    summarise_all(sum)

    character_data <- vf_info %>%
    group_by(VF_ID) %>%
    summarise_all(~first(.))

    select_numeric_columns <- function(df) {
    df %>% select(where(is.numeric))
    }

    heatmap_data_summarized <- bind_cols(character_data, heatmap_data_summarized)
    heatmap_data_summarized <- heatmap_data_summarized %>%
    mutate(
        VFC = str_extract(VFC_ID, "VFC\\d+"),
        VF = str_extract(VF_ID, "VF\\d+")
    ) %>%
    { print(select(., VFC_ID, VFC, VF_ID, VF)); . } %>%
    mutate(
        rowsum = rowSums(select_numeric_columns(select(., 8:ncol(.))), na.rm = TRUE)
    
    ) %>%
    { print(select(., VFC_ID, VF_ID, rowsum)); . } %>%
    group_by(VFC) %>%
    arrange(VFC, desc(rowsum)) %>%
    mutate(
        row_index = row_number()
    ) %>%
    { print(select(., VFC, row_index)); . } %>%
    ungroup() %>%
    arrange(VFC, row_index)

    print(head(heatmap_data_summarized))

    # VF 수가 90개 이상일 때 legend 줄이기
    if(n_distinct(as.character(heatmap_data_summarized$VF)) > 90) {
    top_90_vf <- heatmap_data_summarized %>%
        group_by(VF) %>%
        summarise(total_rowsum = sum(rowsum)) %>%
        top_n(90, total_rowsum) %>%
        pull(VF)
    heatmap_data_summarized <- heatmap_data_summarized %>%
        mutate(VF_display = ifelse(VF %in% top_90_vf, VF, "Other"))
    } else {
    heatmap_data_summarized$VF_display <- heatmap_data_summarized$VF
    }
    print(head(heatmap_data_summarized))


    heatmap_data_summarized$VFC <- factor(heatmap_data_summarized$VFC, levels = unique(heatmap_data_summarized$VFC))
    heatmap_data_summarized$VF_display <- factor(heatmap_data_summarized$VF_display, levels = unique(heatmap_data_summarized$VF_display))

    heatmap_data_summarized$VF_ID <- factor(heatmap_data_summarized$VF_ID)
    heatmap_data_summarized$VFC_ID <- factor(heatmap_data_summarized$VFC_ID)

    set.seed(33)
    vf_names <- unique(heatmap_data_summarized$VF_ID)
    vfc_categories <- unique(heatmap_data_summarized$VFC_ID)
    vf_colors <- rainbow(length(vf_names))
    vfc_colors <- rainbow(length(vfc_categories))
    vf_color_map <- setNames(vf_colors, vf_names)
    vfc_color_map <- setNames(vfc_colors, vfc_categories)
    head(vf_color_map)
    head(vfc_color_map)
    # heatmap_data_summarized$VF_ID <- factor(heatmap_data_summarized$VF_ID, levels = vf_names)
    # heatmap_data_summarized$VFC_ID <- factor(heatmap_data_summarized$VFC_ID, levels = vfc_categories)
    heatmap_data_summarized$VF_ID <- factor(heatmap_data_summarized$VF_ID, levels = names(vf_color_map))
    heatmap_data_summarized$VFC_ID <- factor(heatmap_data_summarized$VFC_ID, levels = names(vfc_color_map))

    all(names(vf_color_map) %in% levels(heatmap_data_summarized$VF_ID)) # Should return TRUE
    all(names(vfc_color_map) %in% levels(heatmap_data_summarized$VFC_ID)) # Should return TRUE

    head(heatmap_data_summarized)
    # metadata add 
    rownames(metadata) <- metadata[,1]

    selected_columns <- c("Completeness", "Contamination", "classification", colnames(metadata[selected_colname])) #meta1380 %>% select(ncol(.)))
    meta_filtered_forvis <- metadata[, selected_columns]
    head(meta_filtered_forvis)
    # meta_filtered_forvis$colnames(meta_filtered_forvis[selected_colname]) <- replace(meta_filtered_forvis$colnames(metadata[selected_colname]),
    #                                           meta_filtered_forvis$colnames(metadata[selected_colname])=='',"NA")
    meta_filtered_forvis <- meta_filtered_forvis %>%
    mutate(!!selected_colname := replace(.[[selected_colname]], .[[selected_colname]] == "", "NA"))

    print(meta_filtered_forvis)

    classification_split <- strsplit(as.character(meta_filtered_forvis$classification), ";")
    classification_df <- do.call(rbind, classification_split)
    colnames(classification_df) <- c("Domain", "Phylum", "Class", "Order", "Family", "Genus", "Species")
    classification_df <- as.data.frame(classification_df)

    meta_filtered_forvis <- cbind(meta_filtered_forvis[, -which(colnames(meta_filtered_forvis) == "classification")], classification_df)
    head(meta_filtered_forvis)

    meta_filtered_forvis_ordered <- meta_filtered_forvis[match(colnames(heatmap_data), rownames(meta_filtered_forvis)),]


    # top_annotation <- HeatmapAnnotation(df = meta_filtered_forvis_ordered,
    #                                     annotation_name_gp = gpar(fontsize = 7)) 

    print(levels(heatmap_data_summarized$VF_ID))
    print(levels(heatmap_data_summarized$VFC_ID))
    head(heatmap_data_summarized)

    row_annotation <-HeatmapAnnotation(
    VF_Name = heatmap_data_summarized$VF_display,
    VFcategory = heatmap_data_summarized$VFC,  
    #VF_ID = heatmap_data_summarized$VF_ID,
    #VFC_ID = heatmap_data_summarized$VFC_ID,
    which='row',
        annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", fontface = "bold"),
    annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )

    row_annotation_hover <- HeatmapAnnotation(
    VF_ID = heatmap_data_summarized$VF_ID,
    VFC_ID = heatmap_data_summarized$VFC_ID,
    show_annotation_name = FALSE, 
    show_legend = FALSE,
    which = 'row',
    height = unit(0, "mm")  
    )


    vfdb_matrix<- heatmap_data_summarized[,8:(ncol(heatmap_data_summarized) -5)]



    #asdasdasd
    breaks <- c(0, min(vfdb_matrix[vfdb_matrix>0]), max(vfdb_matrix))
    print(breaks)
    #doncha --> solved  last 5 field were attached 
    colors <- c("lightgrey", "white", "orange")
    vfdb_matrix <- as.matrix(heatmap_data_summarized[,8:(ncol(heatmap_data_summarized)-5)])
                                            
    # print(vfdb_matrix[(nrow(vfdb_matrix) - 5): nrow(vfdb_matrix), (ncol(vfdb_matrix) - 5): ncol(vfdb_matrix)])
    # print(vfdb_matrix[1:3,1:3])

    if (length(unique(as.vector(vfdb_matrix))) == 1) {
    my_color_function <- "orange"
    } else {
    my_color_function <- colorRamp2(breaks,colors)
    }

    basic_metadata <- meta_filtered_forvis_ordered[, !colnames(meta_filtered_forvis_ordered) %in% c(selected_colname,"Domain", "Phylum", "Class", "Order", "Family")]
    user_metadata <- meta_filtered_forvis_ordered[, selected_colname, drop = FALSE]
    print("Whatthe?4")

    print(vfdb_matrix[(nrow(vfdb_matrix) - 5):nrow(vfdb_matrix), (ncol(vfdb_matrix) - 5):ncol(vfdb_matrix)])

    print(vfdb_matrix[1:3,1:12])

    top_annotation_boxplot <- HeatmapAnnotation(Average_value = anno_boxplot(as.matrix(vfdb_matrix), axis = TRUE, height = unit(1.0, "cm"),
                                axis_param = list(labels_rot = 0)),
    annotation_name_side = "left", annotation_name_rot = 0,
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", fontface="bold")
    )

    print("Whatthe?5")
    top_annotation_basic <- HeatmapAnnotation(
    df = basic_metadata,
    annotation_name_side = "left",
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", fontface="bold"),
    annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )
    print("Whatthe?6")
    top_annotation_user <- HeatmapAnnotation(
    df = user_metadata,
    annotation_name_side = "left",
    annotation_name_gp = gpar(fontsize = 11, fontfamily = "Courier", col = "red", fontface="bold"),
    annotation_legend_param = list(
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    )
    )

    split_data <- split(as.data.frame(t(vfdb_matrix)), meta_filtered_forvis_ordered[, selected_colname])
    split_matrix <- do.call(cbind, lapply(split_data, function(x) colMeans(x, na.rm = TRUE)))

    distribution_colors <- scales::hue_pal()(ncol(split_matrix))
    distribution_legend <- Legend(
        labels = colnames(split_matrix),
        legend_gp = gpar(fill = distribution_colors),
        title = "Virulence_factor_averages",
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface="bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")    
    )

    left_annotation <- rowAnnotation(
    Virulence_factor_averages= anno_points(split_matrix, 
                                pch = 1:ncol(split_matrix),
                                size = unit(1, "mm"),
                                title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface="bold"),
                                gp = gpar(col = scales::hue_pal()(ncol(split_matrix))),
                                width = unit(3, "cm")
    ),  
    annotation_name_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface="bold")
    )


    ht1 <- Heatmap(
    as.matrix(heatmap_data_summarized[,8:(ncol(heatmap_data_summarized)-5)]),
    name = "Virulence Factors",
    col = my_color_function,
    top_annotation = c(top_annotation_boxplot, top_annotation_basic, top_annotation_user),
    right_annotation = c(row_annotation,row_annotation_hover),
    #right_annotation = row_annotation,
    left_annotation = left_annotation,
    show_row_names = FALSE,
    show_column_names = FALSE,
    show_column_dend = FALSE,
    row_order = order(as.integer(factor(heatmap_data_summarized$VFC)), heatmap_data_summarized$row_index),  # VFC,VF arrange
    column_split  = meta_filtered_forvis_ordered[,selected_colname],
    heatmap_legend_param = list(
        legend_direction = "horizontal",
        title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface="bold"),
        labels_gp = gpar(fontsize = 11, fontfamily = "Courier")
    ),
    row_names_gp = gpar(fontsize = 11, fontfamily = "Courier"),
    column_names_gp = gpar(fontsize = 11, fontfamily = "Courier"),
    column_title_gp = gpar(fontsize = 12, fontfamily = "Courier", fontface = "bold", col = "blue")  
    )
    # Save heatmap to file
    output_file <- "heatmap_VFDB.pdf"

    pdf_width <- (2.5*ncol(vfdb_matrix) + 90 + 110 + 100) / 25.4
    pdf_height <- (2.5*nrow(vfdb_matrix) + 45 + 40 + 40) / 25.4

    if (pdf_width >= 20.9) {
    pdf_width = 20.9
    }

    if (pdf_height >= 15) {
    pdf_height = 15.65
    }

    library(ragg)
    library(ComplexHeatmap)
    library(circlize)
    library(InteractiveComplexHeatmap)

    ht1 <- draw(ht1,
        padding = unit(c(2, 2, 2, 2), "cm"),
        annotation_legend_list = list(distribution_legend),
        annotation_legend_side = "left"
    )
    # pdf(file = output_file, width = pdf_width, height = pdf_height)
    # #pdf(file = output_file, width = 20, height = 15)
    # draw(heatmap)
    # dev.off()

    return(ht1)
#htShiny(heatmap, output_ui_float = TRUE, save = output_html)
}

# UI 정의
ui <- fluidPage(
  titlePanel("Integrated Heatmap Viewer"),
  sidebarLayout(
    sidebarPanel(
      selectInput("heatmap_type", "Select Heatmap Type:",
                  choices = c("CARD", "dbCAN", "KEGG", "VFDB")),
      conditionalPanel(
        condition = "input.heatmap_type != 'KEGG'",
        selectInput("data_type", "Select Data Type:",
                    choices = c("Gene PA", "Gene Count"))
      ),
      numericInput("meta_col", "Metadata Column Number:", value = 37, min = 1)
    ),
    mainPanel(
      InteractiveComplexHeatmapOutput("heatmap", width = "20in", height = "15in")
    )
  )
)

# 서버 로직
server <- function(input, output, session) {
  heatmap_data <- reactive({
    # 각 heatmap 유형에 따라 적절한 함수 호출
    if (input$heatmap_type == "CARD") {
      input_file <- ifelse(input$data_type == "Gene PA", "gene_PA_CARD_added.csv", "gene_count_CARD_added.csv")
      create_card_heatmap(input_file, "test.csv", input$meta_col)
    } else if (input$heatmap_type == "dbCAN") {
      input_file <- ifelse(input$data_type == "Gene PA", "dbcan_hmmerfamily_PA_matrix.csv", "dbcan_hmmerfamily_count_matrix.csv")
      create_dbcan_heatmap(input_file, "test.csv", input$meta_col)
    } else if (input$heatmap_type == "KEGG") {
      create_kegg_heatmap("ko_matrix.csv", "test.csv", input$meta_col, 0.5)
    } else if (input$heatmap_type == "VFDB") {
      input_file <- ifelse(input$data_type == "Gene PA", "gene_PA_VFDB_added.csv", "gene_count_VFDB_added.csv")
      create_vfdb_heatmap(input_file, "test.csv", input$meta_col)
    }
  })
  
  output$heatmap <- renderInteractiveComplexHeatmap({
    InteractiveComplexHeatmap(heatmap_data(), output_ui_float = TRUE)
  })
}

# Shiny 앱 실행
shinyApp(ui = ui, server = server)