get_unique_values <- function(x) {
  unique_text <- x$unfiltered_obs_data %>%
    filter(
      ONOFFTX != "OFF"
    ) %>%
    select(where(is.character)) %>%
    pivot_longer(everything()) %>%
    group_by(name, value) %>%
    summarize(count = n(), .groups = "drop") %>%
    filter(name %in% c(
      "Species",
      x$optional_fields %>%
        filter(enabled) %>%
        pull(field)
    )) %>%
    filter(
      !is.na(value),
      name != "Comments"
    ) %>%
    arrange(name, desc(count))

  x$unique_text <- unique_text

  unique_integer <- x$unfiltered_obs_data %>%
    filter(
      ONOFFTX != "OFF"
    ) %>%
    select(where(is.integer)) %>%
    pivot_longer(everything()) %>%
    group_by(name, value) %>%
    summarize(count = n(), .groups = "drop") %>%
    filter(name %in% c(x$optional_fields %>%
      filter(enabled) %>%
      pull(field))) %>%
    filter(
      !is.na(value),
      name != "Record"
    ) %>%
    arrange(name, desc(count))

  x$unique_integer <- unique_integer

  x
}

observeEvent(input$update_after_global_change, {
  if (input$update_after_global_change == TRUE) {
    withProgress(message = "Reprocessing Data", value = 0, {
      setProgress(0.05, detail = "Generating tracks")
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_tracks()")
      x <- generate_tracks(x)
      setProgress(0.25, detail = "Splitting transects for NPPSD")
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_nppsd_splits()")
      x <- generate_nppsd_splits(x)
      setProgress(0.5, detail = "Splitting non-NPPSD transects")
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_nps_splits()")
      x <- generate_nps_splits(x)

      setProgress(0.75, detail = "Building transects")
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_transects()")
      x <- generate_transects(x)
      setProgress(0.90, detail = "Building observations")
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_observations()")
      x <- generate_observations(x)

      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call make_tbl_location()")
      x <- make_tbl_location(x)
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call make_tbl_data_obs()")
      x <- make_tbl_data_obs(x)
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call make_nps_transects()")
      x <- make_nps_transects(x)
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call make_nps_obs()")
      x <- make_nps_obs(x)
    })

    console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call do_backup()")
    do_backup(x$all_obs_data, x$transects, x$raw_track_points)
  }
})

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

unique_text_proxy <- dataTableProxy("unique_text")

observeEvent(input$unique_text_cell_edit, {
  console_log("unique_values.r", "observeEvent(unique_text_cell_edit) start")
  info <- input$unique_text_cell_edit
  i <- info$row
  j <- info$col + 1
  v <- info$value

  field <- x$unique_text[i, ]$name
  original_value <- x$unique_text[i, ]$value

  unchanged_rows <- x$unfiltered_obs_data %>%
    filter(
      is.na(get(field)) |
        get(field) != !!original_value
    )
  changed_rows <- x$unfiltered_obs_data %>%
    filter(get(field) == !!original_value) %>%
    mutate(!!field := v)

  console_log("unique_values.r", glue("observeEvent(unique_text_cell_edit) unchanged: {nrow(unchanged_rows)}, changed: {nrow(changed_rows)}"))
  console_log("unique_values.r", "observeEvent(unique_text_cell_edit) replace unfiltered_obs_data")
  x$unfiltered_obs_data <- bind_rows(unchanged_rows, changed_rows) %>%
    arrange(timestamp)

  if (input$update_after_global_change == TRUE) {
    if (field == "TripID" | field == "Transect") {
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) NULL track_lines, splits, transects, all_obs_data")
      x$track_lines <- NULL
      x$nppsd_split <- NULL
      x$nps_split <- NULL
      x$transects <- NULL
      x$all_obs_data <- NULL
    }

    withProgress(message = "Reprocessing Data", value = 0, {
      setProgress(0.05, detail = "Generating tracks")
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_tracks()")
      x <- generate_tracks(x)
      if (field == "TripID" | field == "Transect") {
        setProgress(0.25, detail = "Splitting transects for NPPSD")
        console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_nppsd_splits()")
        x <- generate_nppsd_splits(x)
        setProgress(0.5, detail = "Splitting non-NPPSD transects")
        console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_nps_splits()")
        x <- generate_nps_splits(x)
      }

      setProgress(0.75, detail = "Building transects")
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_transects()")
      x <- generate_transects(x)
      setProgress(0.90, detail = "Building observations")
      console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call generate_observations()")
      x <- generate_observations(x)

      if (field == "TripID" | field == "Transect") {
        console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call make_tbl_location()")
        x <- make_tbl_location(x)
        console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call make_tbl_data_obs()")
        x <- make_tbl_data_obs(x)
        console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call make_nps_transects()")
        x <- make_nps_transects(x)
        console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call make_nps_obs()")
        x <- make_nps_obs(x)
      }
    })

    console_log("unique_values.r", "observeEvent(unique_text_cell_edit) call do_backup()")
    do_backup(x$all_obs_data, x$transects, x$raw_track_points)
  }

  console_log("unique_values.r", "observeEvent(unique_text_cell_edit) end")
})

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

unique_integer_proxy <- dataTableProxy("unique_integer")

observeEvent(input$unique_integer_cell_edit, {
  info <- input$unique_integer_cell_edit
  i <- info$row
  j <- info$col + 1
  v <- as.integer(info$value)

  field <- x$unique_integer[i, ]$name
  original_value <- as.integer(x$unique_integer[i, ]$value)

  unchanged_rows <- x$unfiltered_obs_data %>%
    filter(get(field) != !!original_value)
  changed_rows <- x$unfiltered_obs_data %>%
    filter(get(field) == !!original_value) %>%
    mutate(!!field := v)

  x$unfiltered_obs_data <- bind_rows(unchanged_rows, changed_rows) %>%
    arrange(timestamp)

  if (input$update_after_global_change == TRUE) {
    withProgress(message = "Reprocessing Data", value = 0, {
      setProgress(0.05, detail = "Generating tracks")
      x <- generate_tracks(x)
      if (field == "Transect") {
        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)
  }
})
