generate_transects <- function(x) {
  console_log("generate_transects.r", glue("generate_transects()"))
  suppressWarnings(
    transects <- x$unfiltered_obs_data %>%
      filter(
        ONOFFTX != "OFF"
      ) %>%
      group_by(TripID, Transect) %>%
      summarize(
        port_obs = max(PortObs, na.rm = TRUE),
        all_port_obss = unique_str_agg(PortObs),
        starboard_obs = max(StarboardObs, na.rm = TRUE),
        all_starboard_obss = unique_str_agg(StarboardObs),
        TxWidth = max(TxWidth, na.rm = TRUE),
        all_trans_width = unique_str_agg(TxWidth),
        Vessel = max(Vessel, na.rm = TRUE),
        all_vessel = unique_str_agg(Vessel),
        Weather = max(Weather, na.rm = TRUE),
        all_weather = unique_str_agg(Weather),
        CloudCover = max(CloudCover, na.rm = TRUE),
        all_cloud_cover = unique_str_agg(CloudCover),
        FogConc = max(FogConc, na.rm = TRUE),
        all_fog_conc = unique_str_agg(FogConc),
        IceType = max(IceType, na.rm = TRUE),
        all_ice_type = unique_str_agg(IceType),
        IceConc = max(IceConc, na.rm = TRUE),
        all_ice_conc = unique_str_agg(IceConc),
        .groups = "drop"
      ) %>%
      ungroup() %>%
      mutate(
        po_all = if_else(port_obs != all_port_obss, all_port_obss, ""),
        so_all = if_else(
          starboard_obs != all_starboard_obss,
          all_starboard_obss,
          ""
        ),
        tw_all = if_else(TxWidth != all_trans_width, all_trans_width, ""),
        vessel_all = if_else(Vessel != all_vessel, all_vessel, ""),
        wx_all = if_else(Weather != all_weather, all_weather, ""),
        cloud_all = if_else(CloudCover != all_cloud_cover, all_cloud_cover, ""),
        fog_all = if_else(FogConc != all_fog_conc, all_fog_conc, ""),
        icet_all = if_else(IceType != all_ice_type, all_ice_type, ""),
        icec_all = if_else(IceConc != all_ice_conc, all_ice_conc, ""),
      ) %>%
      inner_join(x$track_centroids, by = c("TripID", "Transect")) %>%
      select(-geometry) %>% # remove points
      inner_join(x$track_lines, by = c("TripID", "Transect", "Date")) %>%
      mutate(
        area_sampled_km2 = as.numeric(gsub(
          " *([0-9]+).*",
          "\\1",
          TxWidth
        )) /
          1000 *
          length_km,
        invalid_columns = NA
      ) %>%
      select(-c(starts_with("all_"))) %>%
      select(
        TripID,
        Transect,
        start_time,
        end_time,
        TxWidth,
        tw_all,
        length_km,
        area_sampled_km2,
        port_obs,
        po_all,
        starboard_obs,
        so_all,
        invalid_columns,
        Vessel,
        vessel_all,
        Weather,
        wx_all,
        CloudCover,
        cloud_all,
        FogConc,
        fog_all,
        IceType,
        icet_all,
        IceConc,
        icec_all
      )
  )

  # Any (TripID, Transect) present in the ON-transect data but missing here was
  # dropped by the inner_join()s to track_centroids / track_lines above.
  log_dropped_keys(
    "generate_transects.r",
    "transect dropped by track_centroids/track_lines join",
    x$valid_transects,
    transects,
    c("TripID", "Transect")
  )

  if (
    x$optional_fields %>%
      filter(field == "Vessel") %>%
      pull(enabled) ==
      FALSE
  ) {
    transects <- transects %>%
      select(-c(Vessel, vessel_all))
  }
  if (
    x$optional_fields %>%
      filter(field == "Weather") %>%
      pull(enabled) ==
      FALSE
  ) {
    transects <- transects %>%
      select(-c(Weather, wx_all))
  }
  if (
    x$optional_fields %>%
      filter(field == "CloudCover") %>%
      pull(enabled) ==
      FALSE
  ) {
    transects <- transects %>%
      select(-c(CloudCover, cloud_all))
  }
  if (
    x$optional_fields %>%
      filter(field == "FogConc") %>%
      pull(enabled) ==
      FALSE
  ) {
    transects <- transects %>%
      select(-c(FogConc, fog_all))
  }
  if (
    x$optional_fields %>%
      filter(field == "IceType") %>%
      pull(enabled) ==
      FALSE
  ) {
    transects <- transects %>%
      select(-c(IceType, icet_all))
  }
  if (
    x$optional_fields %>%
      filter(field == "IceConc") %>%
      pull(enabled) ==
      FALSE
  ) {
    transects <- transects %>%
      select(-c(IceConc, icec_all))
  }

  transects$invalid_columns <- validate_transects(transects)
  transects$edited <- date(NA)
  transects$delete <- NA

  double_column_names <- transects %>%
    select(where(
      ~ is_double(.) &
        !inherits(., "Date") &
        !inherits(., "POSIXt") &
        !inherits(., "hms")
    )) %>%
    names()
  columns_to_round <- ui_column_vector(names(transects), double_column_names)

  disable_column_names <- c(
    "TripID",
    "Transect",
    "start_time",
    "end_time",
    "length_km",
    "area_sampled_km2",
    "invalid_columns",
    "nppsd_split_id",
    "split_id",
    "edited"
  )
  columns_to_disable <- ui_column_vector(names(transects), disable_column_names)

  sort_column_names <- c(
    "invalid_columns",
    "TripID",
    "Transect"
  )
  sort_columns <- ui_sort_options(names(transects), sort_column_names)

  x$transects <- transects
  x$transects_columns_to_round <- columns_to_round
  x$transects_columns_to_disable <- columns_to_disable
  x$transects_sort_columns <- sort_columns
  x$original_transects <- transects %>%
    filter(FALSE)

  console_log("generate_transects.r", glue("generate_transects() end"))
  x
}
