library(rjson)
library(shiny)
library(bslib)
library(leaflet)
library(sf)
library(htmltools)
library(dplyr)
library(purrr)
library(ggplot2)
library(ggthemes)
library(stringr)
library(plotly)
# Json of Crime Reports
crime_json <- fromJSON(file="data.json")
get_bezirk_by_stadtteil <- function(name) {
  parents <- names(crime_json)[sapply(crime_json, function(item) name %in% names(item))]
  
  if (length(parents) == 0) return(NULL)
  parents
}

map_data_to_table <- function(bezirk, stadtteil, year) {
  year <- as.character(trimws(year))
  map_df(names(crime_json[[bezirk]][[stadtteil]]), function(crime) {
    row <- crime_json[[bezirk]][[stadtteil]][[crime]][[year]]
    
    tibble(
      Name = crime,
      `Erfasste Fälle`      = as.integer(row[["Erfasste Fälle"]]),
      `Aufgeklärte Fälle`   = as.integer(row[["Aufgeklärte Fälle"]]),
      `Aufklärung relativ`  = paste(row[["Aufklärung relativ"]], "%", sep=""),
    )
  })
}

map_data_to_top3_plot <- function(bezirk, stadtteil, year) {
  year <- as.character(trimws(year))
  req(bezirk)
  req(stadtteil)
  req(year)
  komplettes_tibble <- map_df(names(crime_json[[bezirk]][[stadtteil]]), function(crime) {
    row <- crime_json[[bezirk]][[stadtteil]][[crime]][[year]]
    tibble(
      Name = str_wrap(crime, width = 25),
      Erfasst = as.integer(row[["Erfasste Fälle"]]),
    )
  })
  # Sortieren und Beschränken auf die Ränge 2, 3 und 4
  top_3_tibble <- komplettes_tibble %>%
    # Sortieren: Absteigend nach "Erfasste Fälle". Der höchste Wert ist nun in Zeile 1.
    arrange(desc(Erfasst)) %>% 
    # Beschränken: Wählt die Zeilen 2, 3 und 4 aus.
    # Dies sind die Ränge 2, 3 und 4.
    slice(2:4)
  
  return(top_3_tibble)
}

map_data_to_plot <- function(locations, crimes, year) {
  year <- as.character(trimws(year))
  req(locations)
  req(crimes)
  req(year)
  
  return(map_df(locations, function(loc) {
    bezirk <- ""
    stadtteil <- ""
    if (substring(loc, 1, 6) == "Bezirk") {
      bezirk <- substring(loc, 8, nchar(loc))
      stadtteil <- loc
    }
    else {
      bezirk <- get_bezirk_by_stadtteil(loc)
      stadtteil <- loc
    }
    
    komplettes_tibble <- map_df(crimes, function(crime) {
      row <- crime_json[[bezirk]][[stadtteil]][[crime]][[year]]
      tibble(
        Name = str_wrap(crime, width = 25),
        Erfasst = as.integer(row[["Erfasste Fälle"]]),
        Location = loc
      )
    })
  }) %>%
    arrange(desc(Erfasst))
  )
}

get_intensity_df <- function(crime_json, delikt, jahr = "2024", feld = "Erfasste Fälle") {
  do.call(rbind, lapply(names(crime_json), function(bezirk) {
    stadtteile <- crime_json[[bezirk]]
    data.frame(
      bezirk = bezirk,
      stadtteil = names(stadtteile),
      intensity = sapply(stadtteile, function(st) {
        
        # sicherer Zugriff (verhindert Fehler bei fehlenden Einträgen)
        val <- st[[delikt]][[jahr]][[feld]]
        
        if (is.null(val)) NA else val
      }),
      row.names = NULL
    )
  }))
}

#GeoJson for Bezirke
geo_bezirke <- st_read("geobezirke-parsed.json")
geo_bezirke <- st_transform(geo_bezirke, crs = 4326)
geo_bezirke$leaflet_id <- paste("bez_", geo_bezirke$bezirk, sep="")

#GeoJson for Stadtteile
geo_stadtteile <- st_read("geostadtteile-parsed.json")
geo_stadtteile <- st_transform(geo_stadtteile, crs = 4326)
geo_stadtteile$leaflet_id <- paste("std_", geo_stadtteile$stadtteil, sep="")
bezirke <- sort(names(crime_json))

list_of_crimes <- sort(c(unique(unlist(
  lapply(crime_json, function(a) {
    unlist(
      lapply(a, function(b) {
        names(b)
      }),
      use.names = FALSE
    )
  }),
  use.names = FALSE
)), ""))

auswahlmöglichkeiten <- crime_json %>%
  # 1. map(names) wendet names() auf jedes Element der ersten Ebene, wie Bezirke ("A", "B", "C") an.
  #    Ergebnis: Eine Liste von Vektoren (z.B. list(c("aa1", "aa2"), c("bb1", "bb2"), c("cc1"))), hier: Stadtteile
  map(names) %>%
  # 2. unlist() vereint alle diese Vektoren zu einem einzigen Vektor.
  #    Ergebnis: c("aa1", "aa2", "bb1", "bb2", "cc1")
  unlist() %>%
  # 3. unique(): auf Nummer sicher gehen, dass die Stadtteile alle eindeutig sind.
  unique() %>%
  sort() %>%
  setdiff("Alle")