freq_forest_module_ui <- function(id) {
  ns <- shiny::NS(id)
  tagList(
    actionButton(ns("run"), "Generate plots", icon = icon("arrow-turn-down")),
    actionButton(ns("run_all"), "Run all modules", icon = icon("forward-fast")),
    div(class = "freq_forest",
      layout_columns(
        col_widths = rep(6, 6),  # six items: 2 per row
        row_heights = c("auto", "auto", "auto"),  # three rows
        p("Limits of the x-axis for all studies:"),
        p("Limits of the x-axis with selected studies excluded:"),
        numericInput(ns("xmin_all"), "Minimum", 0),
        numericInput(ns("xmin_sub"), "Minimum", 0),
        numericInput(ns("xmax_all"), "Maximum", 0),
        numericInput(ns("xmax_sub"), "Maximum", 0),
      ),
      download_button_pair(id)
    )
  )
}

freq_forest_module_server <- function(id, common, parent_session) {
  moduleServer(id, function(input, output, session) {

  hide_and_show("freq_forest")

  observeEvent(input$run, {
    # WARNING ####
    if (is.null(common$configured_data)){
      common$logger |> writeLog(type = "error", go_to = "setup_configure",
                                 "Please configure the analysis first in the Setup section")
      return()
    }
    # TRIGGER
    trigger("freq_forest")
  })

  observe({
    watch("freq_all")
    req(common$configured_data$freq)
    min_max <- freq_forest_limits(common$configured_data$freq, common$configured_data$outcome)
    updateNumericInput(session, "xmin_all", value = min_max[1], step = format_step(min_max[1]))
    updateNumericInput(session, "xmax_all", value = min_max[2], step = format_step(min_max[2]))

    # prevent errors when set to 0
    if (common$configured_data$outcome == "binary"){
      updateNumericInput(session, "xmin_all", min = 0.01)
    }
  })

  observe({
    watch("setup_exclude")
    req(common$subsetted_data$freq)
    min_max <- freq_forest_limits(common$subsetted_data$freq, common$subsetted_data$outcome)
    updateNumericInput(session, "xmin_sub", value = min_max[1], step = format_step(min_max[1]))
    updateNumericInput(session, "xmax_sub", value = min_max[2], step = format_step(min_max[2]))

    # prevent errors when set to 0
    if (common$configured_data$outcome == "binary"){
      updateNumericInput(session, "xmin_sub", min = 0.01)
    }
  })

  result_all <- reactive({
    watch("freq_all")
    req(watch("freq_forest") > 0)
    common$meta$freq_forest$used <- TRUE
    common$meta$freq_forest$xmin_all <- as.numeric(input$xmin_all)
    common$meta$freq_forest$xmax_all <- as.numeric(input$xmax_all)

    freq_forest(common$configured_data,
                as.numeric(input$xmin_all),
                as.numeric(input$xmax_all),
                "Results for all studies")
  })

  result_sub <- reactive({
    watch("setup_exclude")
    req(watch("freq_forest") > 0)
    common$meta$freq_forest$xmin_sub <- as.numeric(input$xmin_sub)
    common$meta$freq_forest$xmax_sub <- as.numeric(input$xmax_sub)

    freq_forest(common$subsetted_data,
                as.numeric(input$xmin_sub),
                as.numeric(input$xmax_sub),
                "Results with selected studies excluded")
  })

  output$plot_sub <- renderUI({
    svg_container(
        result_sub()
    )
  })

  output$plot_all <- renderUI({
    svg_container(
        result_all()
    )
  })

  output$download_all <- downloadHandler(
    filename = function(){
      paste0("MetaInsight_frequentist_forest_all.", common$download_format)},
    content = function(file){
      write_plot(result_all(), file)
    }
  )

  output$download_sub <- downloadHandler(
    filename = function(){
      paste0("MetaInsight_frequentist_forest_sub.", common$download_format)},
    content = function(file){
      write_plot(result_sub(), file)
    }
  )

  observeEvent(input$run_all, {
    if (is.null(common$configured_data)){
      common$logger |> writeLog(type = "error", go_to = "setup_configure",
                                "Please configure the analysis first in the Setup section")
      return()
    }
    run_all(COMPONENTS, COMPONENT_MODULES, "freq", common$logger)
  })

  return(list(
    save = function() {list(
      ### Manual save start
      ### Manual save end
      xmin_all = input$xmin_all,
      xmax_all = input$xmax_all,
      xmin_sub = input$xmin_sub,
      xmax_sub = input$xmax_sub)
    },
    load = function(state) {
      ### Manual load start
      ### Manual load end
      updateNumericInput(session, "xmin_all", value = state$xmin_all, step = format_step(state$xmin_all))
      updateNumericInput(session, "xmax_all", value = state$xmax_all, step = format_step(state$xmax_all))
      updateNumericInput(session, "xmin_sub", value = state$xmin_sub, step = format_step(state$xmin_sub))
      updateNumericInput(session, "xmax_sub", value = state$xmax_sub, step = format_step(state$xmax_sub))
    }
  ))
})
}

freq_forest_module_result <- function(id) {
  ns <- NS(id)
  layout_columns(
    uiOutput(ns("plot_all")),
    uiOutput(ns("plot_sub"))
  )
}

freq_forest_module_rmd <- function(common){ list(
  freq_forest_knit = !is.null(common$meta$freq_forest$used),
  freq_forest_xmin_all = common$meta$freq_forest$xmin_all,
  freq_forest_xmax_all = common$meta$freq_forest$xmax_all,
  freq_forest_xmin_sub = common$meta$freq_forest$xmin_sub,
  freq_forest_xmax_sub = common$meta$freq_forest$xmax_sub)
}

