# Observations Tab
output$obs_summary <- renderPrint(
  {
    if (
      is.null(input$input_files) |
        is.null(input$optional_fields_json_file) |
        is.null(input$species_json_file) |
        input$process_data_button == 0
    ) {
      invisible(NULL)
    } else {
      summary_no_hms(x$all_obs_data)
    }
  },
  width = 400
)

output$nppsd_species_crosswalk <- renderDT(
  x$nppsd_species_crosswalk,
  rownames = FALSE,
  editable = list(
    target = "cell",
    disable = list(columns = c(0))
  ),
  options = list(
    pageLength = 10,
    lengthMenu = c(10, 20, 50, 100, 200, 500)
  )
)

nppsd_species_crosswalk_proxy <- dataTableProxy("nppsd_species_crosswalk")

observeEvent(input$nppsd_species_crosswalk_cell_edit, {
  info <- input$nppsd_species_crosswalk_cell_edit
  i <- info$row
  j <- info$col + 1
  v <- info$value

  field <- names(x$nppsd_species_crosswalk[, j])
  original_value <- x$nppsd_species_crosswalk[i, j]
  console_log(
    "observations.r",
    glue(
      "observeEvent(nppsd_species_crosswalk_cell_edit): {field}: {original_value} -> {v}"
    )
  )

  x$nppsd_species_crosswalk[i, j] <- DT::coerceValue(
    v,
    as.matrix(x$nppsd_species_crosswalk[i, j])
  )

  withProgress(message = "Reprocessing Data", value = 0, {
    setProgress(0.05, detail = "Generating tracks")
    x <- generate_tracks(x)
    if (field == "TripID") {
      setProgress(0.25, detail = "Splitting transects for NPPSD")
      x <- generate_nppsd_splits(x)
      setProgress(0.5, detail = "Splitting non-NPPSD transects")
      x <- generate_nps_splits(x)
    }
    setProgress(0.75, detail = "Building transects")
    x <- generate_transects(x)
    setProgress(0.90, detail = "Building observations")
    x <- generate_observations(x)
    x <- make_tbl_location(x)
    x <- make_tbl_data_obs(x)
    x <- make_nps_transects(x)
    x <- make_nps_obs(x)
  })

  do_backup(x$all_obs_data, x$transects, x$raw_track_points)
})

output$dl_nppsd_species_crosswalk <- downloadHandler(
  filename = paste0("nppsd_species_crosswalk_", date(now()), ".csv"),
  content = function(file) {
    write_csv(x$nppsd_species_crosswalk, file, na = "")
  }
)

output$raw_summary <- renderPrint(
  {
    if (
      is.null(input$input_files) |
        is.null(input$optional_fields_json_file) |
        is.null(input$species_json_file) |
        input$process_data_button == 0
    ) {
      invisible(NULL)
    } else {
      summary_no_hms(x$unfiltered_obs_data)
    }
  },
  width = 400
)

# Observations Tab
output$raw_obs <- renderDT(
  x$all_obs_data,
  rownames = FALSE,
  editable = list(
    target = "cell",
    disable = list(columns = x$obs_columns_to_disable)
  ),
  options = list(
    pageLength = 20,
    lengthMenu = c(10, 20, 50, 100, 200, 500),
    order = x$obs_sort_columns,
    columnDefs = list(
      list(
        targets = x$obs_columns_to_round,
        render = JS(
          "function(data, type, row, meta) {",
          "  return Math.round(data * 10000)/10000; }"
        )
      ),
      list(
        visible = FALSE,
        targets = "Record"
      )
    )
  )
)

obs_proxy <- dataTableProxy("raw_obs")

observeEvent(input$raw_obs_cell_edit, {
  info <- input$raw_obs_cell_edit
  i <- info$row
  j <- info$col + 1
  v <- info$value

  field <- names(x$original_obs_data[, j])

  already_copied <- x$original_obs_data %>%
    filter(
      TripID == x$all_obs_data[i, ]$TripID,
      Transect == x$all_obs_data[i, ]$Transect,
      timestamp == x$all_obs_data[i, ]$timestamp
    ) %>%
    nrow()

  if (!already_copied) {
    x$original_obs_data <- rbind(x$original_obs_data, x$all_obs_data[i, ])
  }
  x$all_obs_data[i, j] <- DT::coerceValue(v, as.matrix(x$all_obs_data[i, j]))
  x$all_obs_data[i, "invalid_columns"] <- validate_obs(
    x$all_obs_data[i, ],
    x$valid_species_list
  )
  x$all_obs_data[i, "edited"] <- date(now())
  replaceData(obs_proxy, x$all_obs_data, resetPaging = FALSE, rownames = FALSE)

  if (x$all_obs_data |> filter(!is.na(delete), str_length(delete) > 0) |> nrow() > 0) {
    deleted_rows <- x$all_obs_data |>
      filter(!is.na(delete), str_length(delete) > 0)
    deleted_date <- deleted_rows |> pull(Date)
    deleted_time <- deleted_rows |> pull(Time)
    deleted_species <- deleted_rows |> pull(Species)

    console_log("observations.r", glue("observeEvent(raw_obs_cell_edit): deleting row {i}"))
    x$all_obs_data <- x$all_obs_data %>%
      filter(is.na(delete))

    # Clean up map data
    x$observation_points <- x$observation_points |>
      filter(
        is.na(Date) | is.na(Time) | is.na(Species) |
          Date != deleted_date | Time != deleted_time | Species != deleted_species
      )
  }

  all_obs_data <- x$all_obs_data %>%
    mutate(date = date(timestamp)) %>%
    inner_join(
      x$transects %>% mutate(date = date(start_time)),
      by = c("TripID", "Transect", "date")
    ) %>%
    mutate(
      density = if_else(
        ONOFFTX == "ON",
        as.numeric(Count) / area_sampled_km2,
        as.numeric(NA)
      )
    )

  x$all_obs_data$density <- all_obs_data$density

  x <- make_tbl_location(x)
  x <- make_tbl_data_obs(x)
  x <- make_nps_transects(x)
  x <- make_nps_obs(x)

  do_backup(x$all_obs_data, x$transects, x$raw_track_points)
})

output$dl_obs <- downloadHandler(
  filename = paste0("obs_edited_", date(now()), ".csv"),
  content = function(file) {
    write_csv(x$all_obs_data %>% filter(is.na(delete)), file, na = "")
  }
)

output$original_obs <- renderTable({
  if (
    is.null(input$input_files) |
      is.null(input$optional_fields_json_file) |
      is.null(input$species_json_file) |
      input$process_data_button == 0
  ) {
    invisible(NULL)
  } else {
    x$original_obs_data
  }
})

output$dl_original_obs <- downloadHandler(
  filename = paste0("obs_original_", date(now()), ".csv"),
  content = function(file) {
    write_csv(x$original_obs_data %>% filter(is.na(delete)), file, na = "")
  }
)

# NPS Split Observations Tab
output$nps_obs <- renderDT(
  x$nps_obs,
  rownames = FALSE,
  editable = FALSE,
  options = list(
    pageLength = 20,
    lengthMenu = c(10, 20, 50, 100, 200, 500),
    order = list(list(0, "asc"), list(1, "asc")),
    columnDefs = list(list(
      targets = x$nps_obs_round,
      render = JS(
        "function(data, type, row, meta) {",
        "  return Math.round(data * 10000)/10000; }"
      )
    ))
  )
)

output$dl_nps_obs <- downloadHandler(
  filename = paste0("nps_split_obs_", date(now()), ".csv"),
  content = function(file) {
    write_csv(x$nps_obs, file, na = "")
  }
)

# tbl_DATA_OBS Tab
output$tbl_data_obs <- renderDT(
  x$tbl_data_obs,
  rownames = FALSE,
  editable = FALSE,
  options = list(
    pageLength = 20,
    lengthMenu = c(10, 20, 50, 100, 200, 500),
    columnDefs = list(list(
      targets = c(5),
      render = JS(
        "function(data, type, row, meta) {",
        "  return Math.round(data * 10000)/10000; }"
      )
    ))
  )
)

output$dl_tbl_data_obs <- downloadHandler(
  filename = paste0("tbl_data_obs_", date(now()), ".csv"),
  content = function(file) {
    write_csv(x$tbl_data_obs, file, na = "")
  }
)

# vim: set ft=r fenc=utf-8 tw=80 ts=2 sw=2 sts=2:
