box::use(
  shiny[sidebarLayout, sidebarPanel, mainPanel, p, h4, div, moduleServer, NS, selectInput, dateRangeInput, radioButtons, tags, numericInput, br, downloadButton,downloadHandler, uiOutput, renderUI,reactiveValuesToList,
    conditionalPanel, reactive, req, renderText, textOutput, renderPrint, HTML, updateSelectInput, observe, observeEvent, reactiveVal, verbatimTextOutput,],
  DT[DTOutput, renderDT, datatable],
  shinycssloaders[withSpinner],
  bslib[card, card_header]
)

box::use(
  app/logic/datasets[tc_data],
  app/data_prep/fcts[clean_genotype_columns],
  app/logic/vars[sites]
)

#' @export
ui <- function(id) {
  ns <- NS(id)
  sidebarLayout(
    sidebarPanel(
      width = 3,
      uiOutput(ns("station")),
      # selectInput(ns("site"), "SITE:", choices = c("Arusha", "Ibadan", "Kawanda", "Sendusu")),
      selectInput(ns("dataset"),
                  "DATASET:",
                  choices = c("Crosses (Embryo Rescue)" = "embryo_rescue",
                               "Germinating Embryo" = "germination_ids",
                               "Subcultures" = "subcultures",
                               "Rooting" = "rooting",
                               "Weaning 1/ Sending out" = "weaning1",
                               "Weaning 2" = "weaning2",
                               "Screenhouse Transfer" = "screenhouse",
                               "Hardening" = "hardening",
                               "Open-field" = "openfield"),
                  selected = "germinating_embryos"), br(),

      dateRangeInput(
        ns("daterange"),
        label = HTML('<span>DATE RANGE <span style="color: red; font-size: 12px; font-weight: normal;">(Adjust the date range to focus on specific time periods.)</span></span>'),
        max = Sys.Date(),
        start = lubridate::floor_date(lubridate::ymd(Sys.Date()), 'month'),
        end = Sys.Date()
      ),
      br(),
      shiny::radioButtons(ns("number_per_tube"), "Number of plants/ seeds per test tube/ jar",
                          choices = c("1 plant/test tube", "3 plant2/test tube", "6 plants/test tube", "Equal # of plantlets")),

      numericInput(ns("number_of_copies"), "Number of barcode labels (copies)", value=1, min=1),
      downloadButton(ns("download"), "Download")
    ),
    mainPanel(
      width = 9,
      card(
        height = "700px",
        card_header(textOutput(ns("title"))),
        textOutput(ns("txt")),
        selectInput(ns("scanId"), "Scan barcode(s)", choices = c(""), multiple = T, width = "100%"),
        DTOutput(ns("table")) |>
          withSpinner(type = 7, size = 1)
      ), br(), br(), br(), br()
    )
  )
}

#' @export
server <- function(id, tab, res_auth) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns

    id_col <- reactiveVal(NULL)

    output$title <- renderText({
      if(isTRUE(tab$nav == "Tissue Culture Barcodes")){
        toupper(paste(input$site, ": ", gsub("_", " ", input$dataset)))
      }
    })

    output$station <- renderUI({
      station <- reactiveValuesToList(res_auth)$station
      if(length(station)>0){
        if(station == "All"){
          location <- sites
        } else {
          location <- station
        }
        selectInput(ns("site"), label = HTML('<span>SITE <span style="color: red; font-size: 12px; font-weight: normal;">(You can olny see data from the authorized sites)</span></span>'), choices = location, multiple = FALSE, selected = location[1])
      }

    })

    observe({
      if(isTRUE(tab$nav == "Tissue Culture Barcodes")){
        if(input$dataset =='germination'){
          shinyjs::hide("number_per_tube")
        } else {
          shinyjs::show("number_per_tube")
        }
      }
    })

    data_input <- reactive({

      req(input$site)
      if(isTRUE(tab$nav == "Tissue Culture Barcodes")){

        dataset_name <- paste0(tolower(input$site), "_", input$dataset)

        dt <- readRDS(paste0("app/data/", dataset_name, ".rds")) |>
          dplyr::select(-dplyr::contains("URL")) |>
          clean_genotype_columns()

        date_col <- grep("Date", names(dt), value = TRUE)[1]

        dt <- dt |>
          dplyr::mutate(!!date_col := as.Date(.data[[date_col]])) |>
          dplyr::filter(dplyr::between(.data[[date_col]], input$daterange[1], input$daterange[2])) |>
          dplyr::arrange(desc(.data[[date_col]]))

        dt
      }
    })

    observe({
      id_col <- ifelse(input$dataset == "embryo_rescue", "Crossnumber", "PlantletID")
      id <- unique(data_input()[[id_col]])
      updateSelectInput(session, "scanId",  "Scan IDs to show", choices = c('', id))
      id_col(id_col)
    })

    filtered_data <- reactive({
      dt <- data_input() |>
        dplyr::select(-Location)

      if(length(input$scanId) > 0){
        dt <- dt |>
          dplyr::filter(!!rlang::sym(id_col()) %in% input$scanId)
      }
      dt
    })

    # Data-table
    output$table <- renderDT({
      input$site
      input$dataset

      dt <- filtered_data()
      colnames(dt) <- gsub("_"," ", names(dt))
      datatable(
        dt, rownames=TRUE,
        options = list(scrollX = TRUE)
      )
    })


    # Download labels

    download_input <- reactive({
      dt <- filtered_data()
      embryo_col <- ifelse(input$dataset == "weaning2", "Weaning_2_Plantlets", grep("Number", names(dt), value = T))
      if(input$dataset == "embryo_rescue"){
        dt <- tc_data(
          dt,
          number_per_tube = input$number_per_tube,
          number_of_copies = input$number_of_copies,
          rows_selected = NULL,
          embryo_col = NULL,
          data_type = "embryo"
        )

      } else {
        dt <- tc_data(
          dt,
          number_per_tube = input$number_per_tube,
          number_of_copies = input$number_of_copies,
          rows_selected = NULL,
          embryo_col = embryo_col,
          data_type = "plantlet"
        )
      }

    })


# on click download
  output$download <- downloadHandler(
    filename = function(){
      paste0(input$site,"-", input$dataset,"-", Sys.Date(),".xls")
    },
    content = function(file) {
      writexl::write_xlsx(download_input(), file)
    }
  )



  })
}
