box::use(
  shiny[
    tagList, sidebarLayout, sidebarPanel, mainPanel, div, moduleServer, NS,
    selectInput, tags, downloadButton, downloadHandler, br, reactive, req,
    bindCache, observe, reactiveValuesToList
  ],
  reactable[reactableOutput, renderReactable, reactable, colDef, JS, getReactableState, reactableTheme, reactableLang],
  DT[DTOutput, renderDT, datatable],
  shinycssloaders[withSpinner],
  bslib[card],
  dplyr[select, everything],
  cachem[cache_mem],
  utils[write.csv]
)

box::use(
  app/logic/load_datasets[
    flowering, banana, plantlets, subcultures, rooting, weaning1, weaning2,
    screenhouse, hardening, openfield
  ]
)

#' @export
ui <- function(id) {
  ns <- NS(id)
  tagList(
    sidebarLayout(
      sidebarPanel(
        width = 2,
        selectInput(ns("dataset"), "Select dataset:",
                    choices = c(
                      #"Flowering" = "flowering",
                      "Crosses" = 'banana',
                      "Plantlets" = "plantlets",
                      "Subcultures" = "subcultures",
                      "Rooting" = 'rooting',
                      "Weaning 1" = "weaning1",
                      "Weaning 2" = "weaning2",
                      "Screenhouse" = "screenhouse",
                      "Hardening" = "hardening",
                      "Open-field" = "openfield"
                    ),
                    selected = "banana"
        ),
        br(),
        downloadButton(ns("download_data"), "Download CSV")
      ),
      mainPanel(
        width = 10,
        card(
          full_screen = TRUE,
          reactableOutput(ns("table")) |>
            withSpinner(type = 7, size = 1)
        ), br(), br()
      )
    )
  )
}

#' @export
server <- function(id, tab, res_auth) {
  moduleServer(id, function(input, output, session) {
    # Create cache for dataset loading
    data_cache <- cache_mem(max_size = 500 * 1024^2)

    # Reactive data loader with caching
    data_input <- reactive({
      req(tab$nav == "data" && tab$data == "Raw Data Table")
      location <- reactiveValuesToList(res_auth)$station

      data <- readRDS(paste0("app/data/",tolower(location),"_",input$dataset, ".rds"))
    }) |> bindCache(input$dataset, tab$nav, tab$data)


    # Optimized table renderer
    output$table <- renderReactable({
      req(data_input())
      dt <- data_input()
      colnames(dt) <- gsub("_"," ", names(dt))

      reactable(
        dt,
        defaultColDef = colDef(minWidth = 100, maxWidth = 200, width = 150,
                               headerStyle = list(color = "hsl(203, 15%, 47%)")),
        columns = list(
          `Female Genotype` = colDef(html = TRUE, cell = function(value, index) {
            sprintf('<a href="%s" target="_blank">%s</a>', dt$`Female URL`[index], value)
          }),
          `Male Genotype` = colDef(html = TRUE, cell = function(value, index) {
            sprintf('<a href="%s" target="_blank">%s</a>', dt$`Male URL`[index], value)
          }),
          `Female URL` = colDef(show = FALSE),
          `Male URL` = colDef(show = FALSE)
        ),
        filterable = TRUE,
        searchable = TRUE,
        selection = "multiple",
        onClick = "select",
        minRows = 10,
        highlight = TRUE,
        language = reactableLang(
          noData = "No data found",
          pageInfo = "{rowStart}\u2013{rowEnd} of {rows} data"
        ),
        theme = reactableTheme(
          highlightColor = "#f3fafb",
          borderColor = "hsl(0, 0%, 93%)",
          headerStyle = list(borderColor = "hsl(0, 0%, 90%)")
        )
      )
    })


    selected <- reactive(getReactableState("table", "selected"))

    download_input <- reactive({
      if(is.null(selected())){
        dt <- data_input()
      } else {
        dt <- data_input()[selected(),]
      }
    })

    # Download handler
    output$download_data <- downloadHandler(
      filename = function() {
        paste0(input$dataset, "_", Sys.Date(), ".csv")
      },
      content = function(file) {
        write.csv(download_input(), file, row.names = FALSE)
      }
    )
  })
}
