#' @title Einlesen der beobachteten Bevölkerungsbestände und -bewegungen
#'
#' @param PARAM_INPUTS a single row data frame with the names of the input files
#'
#' @return dataframe BEV_BESTAND
#'
#' @author [MAS BSV](mailto:sekretariat.mas@bsv.admin.ch)
#'
#' @export

mod_input_bev_bestand <- function(PARAM_INPUTS) {
 
    print("Run module: mod_input_bev_bestand")    
    
    #---------------------------------LOAD RData FILES (ESPOP, ERWBEV)-
    
    # Funktion zum Einlesen der RData-Dateien
    loadRData <- function(fileName) {
        temp_env <- new.env()
        load(fileName, envir = temp_env)
        temp_env[[ls(temp_env)[1]]]
    }
    
    # Lade die benötigten RData-Dateien
    ESPOP <- loadRData(file.path(PARAM_INPUTS$path_allgemein_go, "BEVOELKERUNG", PARAM_INPUTS$name_espop)) |>
      pivot_wider(
        names_from = variable,  
        values_from = value    
      ) |>
      arrange(jahr, sex, nat, alt)
    
    BEV_INLAENDER_EPT <- loadRData(file.path(PARAM_INPUTS$path_allgemein_go, "BEVOELKERUNG", PARAM_INPUTS$erwbev_bestand)) %>%
      mutate( # Berechnung von Erwerbsquote und Erwerbsquote in VZÄ, da diese auch für die Szenariodaten verfügbar sind
        erwq=erwbev/erwbev_and_nerwbev*100,
        erwqept=ept/erwbev_and_nerwbev*100
        ) %>%
      select(-erwbev_and_nerwbev) # Variable mit Summe von Erwerbs- und Nichterwerbsbevölkerung gemäss SAKE entfernen (da nicht in Szenariodaten enthalten)
    
    #---------------------------------FRONTALIERS DATA--------------------------
    
    # Funktion zum Einlesen der Sheets "Männer" und "Frauen"
    process_sheet <- function(sheet_name, sex_label) {
      # Datei einlesen mit automatischer Vergabe eindeutiger Spaltennamen
      data <-
        read_excel(
          file.path(PARAM_INPUTS$path_allgemein_go, "BEVOELKERUNG", PARAM_INPUTS$file_frontaliers),
          sheet = sheet_name,
          col_names = FALSE,
          .name_repair = "unique_quiet"
        )
      
      # Spalte B entfernen (zweite Spalte)
      data <- data |> select(-2)
      
      # Spaltennamen setzen basierend auf der zweiten Zeile
      colnames(data) <- c("jahr", as.character(as.numeric(data[2, -c(1, ncol(data))])), "99")
      
      # Entferne erste und dritte Zeile
      data <- data[-c(1, 2, 3), ]
      
      # In tibble umwandeln und auf lange Form bringen
      data |>
        as_tibble() |>
        pivot_longer(
          cols = -jahr, 
          names_to = "alt",
          values_to = "frontaliers"
        ) |>
        mutate(
          jahr = as.numeric(jahr), 
          frontaliers = as.numeric(frontaliers), 
          alt = as.numeric(alt),
          sex = sex_label, 
          nat = "au"
        )
    }
    
    # Daten aus beiden Sheets einlesen
    FRONTALIERS <- bind_rows(
      process_sheet("Männer", "m"),
      process_sheet("Frauen", "f")
    )
    
    
    #---------------------------------SAISONNIERS DATA--------------------------
    
    # Lade und verarbeite die Saisonniers-Daten
    SAISONNIERS <- read_excel(
        file.path(PARAM_INPUTS$path_allgemein_go, "BEVOELKERUNG", PARAM_INPUTS$file_sm),
        sheet = "bestaende",
        skip = 10
    ) %>%
        as_tibble() %>%
        pivot_longer(
            cols = -jahr, # Alle Spalten außer "jahr"
            names_to = "alt", # Alters-Spalte erstellen
            values_to = "saisonniers" # Werte in "saisonniers" speichern
        ) %>%
        mutate(
            alt = as.integer(gsub("age", "", alt, fixed = TRUE)), # "age" aus Alterswerten entfernen
            jahr = as.integer(jahr), # Jahr numerisch formatieren
            nat = "au" # Nationalität hinzufügen
        ) %>%
        crossing(sex = c("m", "f")) %>% # Geschlechter-Kombination
        filter(jahr >= 1971, alt <= 99) # Filtere relevante Jahre und Alter
    
    
    #---------------------------------ASSURES FACULTATIFS DATA------------------
    
    # Importiere die Assures-Facultatifs-Daten
    tfile <- file.path(PARAM_INPUTS$path_allgemein_go, "BEVOELKERUNG", PARAM_INPUTS$file_af)
    
    # Bestimme relevante Sheets (Frauen und Männer)
    sheets_names_sel <- readxl::excel_sheets(tfile) %>%
        grep("^(f_|h_)", ., value = TRUE)
    
    # Funktion zum Lesen und Umformen von Excel-Daten
    af_fct_data <- function(tfile, sheet) {
        suppressMessages( # Suppress "New names" message
            read_excel(tfile, sheet, skip = 1) %>%
                as_tibble() %>%
                select(-TOTAL) %>%  # Entferne TOTAL-Spalte
                rename(jahr = "...1") %>%  # Benenne erste Spalte um
                pivot_longer(-jahr, names_to = "alt", values_to = "assures_facultatifs") %>%
                mutate(
                    alt = as.integer(alt),  # Wandle alt in Integer um
                    jahr = as.integer(jahr)  # Wandle jahr in Integer um
                ) %>%
                filter(alt <= 99) %>%  # Filtere Alterswerte bis 99
                arrange(alt)  # Sortiere nach Alter
        )
    }
    
    # Verarbeite und kombiniere die Assures-Facultatifs-Daten
    ASSURES_FACULTATIFS <- tibble(sheet = sheets_names_sel) %>%
        mutate(
            sex = ifelse(grepl("^f_", sheet), "f", "m"),  # Geschlecht aus Sheetname ableiten
            nat = ifelse(grepl("_ch", sheet), "ch", "au")  # Nationalität aus Sheetname ableiten
        ) %>%
        mutate(data = purrr::map(sheet, ~ af_fct_data(tfile, .x))) %>%  # Daten einlesen
        unnest(data) %>%  # Daten entpacken
        select(jahr, sex, nat, alt, assures_facultatifs)  # Spalten auswählen
    
    
    #---------------------------------ENSURE ALT RANGE 0-99---------------------
    
    # Funktion zur Sicherstellung vollständiger Daten für alt von 0 bis 99 für jahre wo Daten vorhanden sind
    ensure_alt_range <- function(df, value_cols) {
        # Ensure value_cols is treated as a vector
        value_cols <- as.vector(value_cols)
        
        # Create a complete grid with all combinations of jahr, sex, nat, and alt
        complete_grid <- expand_grid(
            jahr = unique(df$jahr),  # All unique years in the dataset
            sex = c("m", "f"),       # Both sexes
            nat = c("ch", "au"),     # Both nationalities
            alt = 0:99               # Age group from 0 to 99
        )
        
        # Summarize and complete the data
        df %>%
            mutate(alt = ifelse(alt >= 100, 99, alt)) %>% # Summiere alt >= 100 in alt == 99
            group_by(jahr, sex, nat, alt) %>%
            summarize(across(all_of(value_cols), \(x) sum(x, na.rm = TRUE)), .groups = "drop") %>% # Summiere Werte
            right_join(complete_grid, by = c("jahr", "sex", "nat", "alt")) %>% # Merge with complete grid
            mutate(across(all_of(value_cols), ~ replace_na(., 0))) # Replace NA with 0 in value_cols
    }
    
    
    # Wende die Normalisierung auf alle relevanten DataFrames an
    ESPOP <- ensure_alt_range(ESPOP, c("bevanfangj","bevendejahr","geburt","tod","einbuergerung","einwanderung","auswanderung","bereinigung"))
    BEV_INLAENDER_EPT <- ensure_alt_range(BEV_INLAENDER_EPT, c("erwbev","ept", "erwq", "erwqept"))
    FRONTALIERS <- ensure_alt_range(FRONTALIERS, "frontaliers")
    SAISONNIERS <- ensure_alt_range(SAISONNIERS, "saisonniers")
    ASSURES_FACULTATIFS <- ensure_alt_range(ASSURES_FACULTATIFS, "assures_facultatifs")
    
    #---------------KORREKTUR REGISTERFEHLER ASSURES_FACULTATIFS----------------
    # Correction des erreurs d'observations des registres pour les années 2002 et 2004 (non reported observations)
    
    ASSURES_FACULTATIFS <- ASSURES_FACULTATIFS %>%
      group_by(sex, nat, alt) %>%
      # Pour 2002 et 2004, remplacer les valeurs par la moyenne des
      # observations de l'année précédente et l'année suivante.
      mutate(assures_facultatifs = if_else(
        jahr %in% c(2002, 2004), 
        ceiling((lag(assures_facultatifs) + lead(assures_facultatifs)) / 2), 
        assures_facultatifs
      )) %>%
      ungroup()
    
    #---------------------------------COMBINE DATA------------------------------
    
    # Kombiniere die verschiedenen Datenquellen
    BEV_BESTAND <- ESPOP %>%
      full_join(BEV_INLAENDER_EPT, by = c("jahr", "sex", "nat", "alt")) %>%
      full_join(FRONTALIERS, by = c("jahr", "sex", "nat", "alt")) %>%
      left_join(SAISONNIERS, by = c("jahr", "sex", "nat", "alt")) %>% # Left-join für Saisonniers, da diese in Rohdaten bis 2065 auf 0 sind
      full_join(ASSURES_FACULTATIFS, by = c("jahr", "sex", "nat", "alt")) %>%
      arrange(jahr, sex, nat, alt)
    
    return(BEV_BESTAND = BEV_BESTAND)
}