# Input Files Tab
output$transects_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$transects)
    }
  },
  width = 400
)

# Transects tab
output$raw_transects <- renderDT(
  x$transects,
  rownames = FALSE,
  editable = list(
    target = "cell",
    disable = list(columns = x$transects_columns_to_disable)
  ),
  options = list(
    pageLength = 20,
    lengthMenu = c(10, 20, 50, 100, 200, 500),
    order = x$transects_sort_columns,
    columnDefs = list(list(
      targets = x$transects_columns_to_round,
      render = JS(
        "function(data, type, row, meta) {",
        "  return Math.round(data * 10000)/10000; }"
      )
    ))
  )
)

transects_proxy <- dataTableProxy("raw_transects")

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

  already_copied <- x$original_transects %>%
    filter(
      TripID == x$transects[i, ]$TripID,
      Transect == x$transects[i, ]$Transect,
      start_time == x$transects[i, ]$start_time
    ) %>%
    nrow()

  if (!already_copied) {
    x$original_transects <- rbind(x$original_transects, x$transects[i, ])
  }

  x$transects[i, j] <- DT::coerceValue(v, as.matrix(x$transects[i, j]))
  x$transects[i, "invalid_columns"] <- validate_transects(x$transects[i, ])
  x$transects[i, "edited"] <- date(now())
  replaceData(
    transects_proxy,
    x$transects,
    resetPaging = FALSE,
    rownames = FALSE
  )

  if (x$transects |> filter(!is.na(delete), str_length(delete) > 0) |> nrow()) {
    deleted_row <- x$transects |>
      filter(!is.na(delete), str_length(delete) > 0)
    deleted_trip_id <- deleted_row$TripID
    deleted_transect <- deleted_row$Transect
    console_log(
      "transects.r",
      glue(
        "observeEvent(raw_transects_cell_edit): deleting {deleted_trip_id} {deleted_transect}"
      )
    )
    console_log(
      "transects.r",
      glue(
        "transect n = {nrow(x$transects)}, all_obs_data n = {nrow(x$all_obs_data)}, raw_track_points n = {nrow(x$raw_track_points)}"
      )
    )
    x$transects <- x$transects |>
      filter(
        is.na(TripID) |
          is.na(Transect) |
          TripID != deleted_trip_id |
          Transect != deleted_transect
      )
    x$all_obs_data <- x$all_obs_data |>
      filter(
        is.na(TripID) |
          is.na(Transect) |
          TripID != deleted_trip_id |
          Transect != deleted_transect
      )
    x$raw_track_points <- x$raw_track_points |>
      filter(
        is.na(TripID) |
          is.na(Transect) |
          TripID != deleted_trip_id |
          Transect != deleted_transect
      )

    # Clean up map data
    x$track_lines <- x$track_lines |>
      filter(
        is.na(TripID) |
          is.na(Transect) |
          TripID != deleted_trip_id |
          Transect != deleted_transect
      )
    x$track_points <- x$track_points |>
      filter(
        is.na(TripID) |
          is.na(Transect) |
          TripID != deleted_trip_id |
          Transect != deleted_transect
      )
    x$observation_points <- x$observation_points |>
      filter(
        is.na(TripID) |
          is.na(Transect) |
          TripID != deleted_trip_id |
          Transect != deleted_transect
      )

    console_log(
      "transects.r",
      glue(
        "transect n = {nrow(x$transects)}, all_obs_data n = {nrow(x$all_obs_data)}, raw_track_points n = {nrow(x$raw_track_points)}"
      )
    )
  }

  # Update area sampled
  x$transects$area_sampled_km2 <- as.numeric(gsub(
    " *([0-9]+).*",
    "\\1",
    x$transects$TxWidth
  )) /
    1000 *
    x$transects$length_km

  # Push transect-level TxWidth and density back to obs data
  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(
      TxWidth = coalesce(TxWidth.y, TxWidth.x),
      density = if_else(
        ONOFFTX == "ON",
        as.numeric(Count) / area_sampled_km2,
        as.numeric(NA)
      )
    )

  x$all_obs_data$density <- all_obs_data$density
  x$all_obs_data$TxWidth <- all_obs_data$TxWidth

  console_log(
    "transects.r",
    "observeEvent(raw_transects_cell_edit), get_unique_values"
  )
  x <- get_unique_values(x)

  x$tbl_location <- make_tbl_location(x)
  x$tbl_data_obs <- make_tbl_data_obs(x)
  x$nps_transects <- make_nps_transects(x)
  x$nps_obs <- make_nps_obs(x)

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

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

output$original_transects <- 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_transects
  }
})

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

# NPS Split Transects tab
output$nps_transects <- renderDT({
  datatable(
    x$nps_transects,
    rownames = FALSE,
    editable = FALSE,
    options = list(
      pageLength = 20,
      lengthMenu = c(10, 20, 50, 100, 200, 500),
      order = list(list(0, "asc")),
      columnDefs = list(
        list(
          targets = x$nps_transects_round,
          render = JS(
            "function(data, type, row, meta) {",
            "  return Math.round(data * 10000)/10000;",
            "}"
          )
        ),
        list(
          targets = x$nps_transects_timestamp_columns,
          render = JS(
            "function(data, type, row, meta) {",
            "  const d = new Date(data);",
            "  return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')}T${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}:${d.getSeconds().toString().padStart(2, '0')}`;",
            "}"
          )
        )
      )
    )
  ) %>%
    formatStyle(
      "master_key",
      "transect_length_km",
      backgroundColor = styleInterval(
        c(x$nps_split_km * 0.05, 2 * x$nps_split_km * 1.05),
        c("darkorange", NA, "darkorange")
      )
    ) %>%
    formatStyle(
      "transect_length_km",
      backgroundColor = styleInterval(
        c(x$nps_split_km * 0.05, 2 * x$nps_split_km * 1.05),
        c("darkorange", NA, "darkorange")
      )
    )
})

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

# tbl_LOCATION Tab
output$tbl_location <- renderDT({
  datatable(
    x$tbl_location,
    rownames = FALSE,
    editable = FALSE,
    options = list(
      pageLength = 20,
      lengthMenu = c(10, 20, 50, 100, 200, 500),
      columnDefs = list(
        list(
          targets = c(8, 9, 13, 14),
          render = JS(
            "function(data, type, row, meta) {",
            "  return Math.round(data * 10000)/10000; }"
          )
        )
      )
    )
  ) %>%
    formatStyle(
      "master_key",
      "transect_length_km",
      backgroundColor = styleInterval(
        c(x$nppsd_split_km * 0.05, 2 * x$nppsd_split_km * 1.05),
        c("darkorange", NA, "darkorange")
      )
    ) %>%
    formatStyle(
      "transect_length_km",
      backgroundColor = styleInterval(
        c(x$nppsd_split_km * 0.05, 2 * x$nppsd_split_km * 1.05),
        c("darkorange", NA, "darkorange")
      )
    )
})

output$dl_tbl_location <- downloadHandler(
  filename = paste0("tbl_location_", date(now()), ".csv"),
  content = function(file) {
    write_csv(
      x$tbl_location %>%
        select(-transect_length_km),
      file,
      na = ""
    )
  }
)

# Tracks Tab
output$tracks_map <- renderLeaflet({
  console_log(
    "transects.r",
    glue("in renderLeaflet")
  )
  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 {
    coords <- st_coordinates(x$track_points$geometry)
    center_lon <- mean(coords[, 1])
    center_lat <- mean(coords[, 2])

    factors <- factor(x$track_lines$Transect)
    pal <- colorFactor(
      palette = plasma(8, begin = 0, end = 0.85),
      domain = factors
    )

    leaflet("tracks_map", data = x$track_lines) %>%
      setView(center_lon, center_lat, zoom = 9) %>%
      # addTiles("http://{s}.tile.opentopomap.org/{z}/{x}/{y}.png")
      addTiles() %>%
      addPolylines(
        group = "tracks",
        color = ~ pal(factor(Transect)),
        popup = ~ paste(
          sep = "<br>",
          paste(
            "Track ",
            htmlEscape(glue(
              "{Transect}_",
              "{year(start_time)}",
              "{sprintf('%02d', month(start_time))}",
              "{sprintf('%02d', day(start_time))}"
            ))
          ),
          paste(start_time, " - ", end_time)
        ),
        label = ~ paste(
          "Track ",
          htmlEscape(glue(
            "{Transect}_",
            "{year(start_time)}",
            "{sprintf('%02d', month(start_time))}",
            "{sprintf('%02d', day(start_time))}"
          ))
        ),
        highlightOptions = highlightOptions(
          color = "red",
          opacity = 1,
          weight = 4,
          fillOpacity = 1,
          bringToFront = TRUE,
          sendToBack = TRUE
        )
      ) %>%
      addCircleMarkers(
        data = x$observation_points,
        group = "observations",
        radius = 1,
        color = "blue",
        clusterOptions = markerClusterOptions(disableClusteringAtZoom = 12),
        label = ~ htmlEscape(glue("#{Record}: {Count} {Species}"))
      ) %>%
      addMouseCoordinates()
  }
})

# TODO: Use geopackage instead, assuming we can write multiple layers into a
# single file
output$dl_transects_shp <- downloadHandler(
  filename <- paste0("seabird_gis_data_", date(now()), ".gpkg"),
  content <- function(fname) {
    if (!dir.exists("geopackages")) {
      dir.create("geopackages")
    }
    gpkg_filename <- glue("geopackages/seabird_gis_data_{date(now())}.gpkg")
    st_write(
      x$track_lines |>
        mutate(
          start_time = format(start_time, "%Y-%m-%d %H:%M:%S"),
          end_time = format(end_time, "%Y-%m-%d %H:%M:%S")
        ),
      dsn = gpkg_filename,
      layer = "track_lines",
      driver = "GPKG",
      delete_layer = TRUE
    )
    st_write(
      x$nps_split |>
        mutate(
          start_time = format(start_time, "%Y-%m-%d %H:%M:%S"),
          end_time = format(end_time, "%Y-%m-%d %H:%M:%S")
        ),
      dsn = gpkg_filename,
      layer = "split_transects",
      driver = "GPKG",
      delete_layer = TRUE
    )
    st_write(
      x$nppsd_split |>
        mutate(
          start_time = format(start_time, "%Y-%m-%d %H:%M:%S"),
          end_time = format(end_time, "%Y-%m-%d %H:%M:%S")
        ),
      dsn = gpkg_filename,
      layer = "nppsd_split_transects",
      driver = "GPKG",
      delete_layer = TRUE
    )
    st_write(
      x$observation_points |>
        mutate(
          timestamp = format(timestamp, "%Y-%m-%d %H:%M:%S")
        ),
      dsn = gpkg_filename,
      layer = "observation_points",
      driver = "GPKG",
      delete_layer = TRUE
    )
    file.copy(gpkg_filename, fname, overwrite = TRUE)
  },
  contentType = "application/gpkg"
)

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