#' @title Projection des sommes de rentes selon le droit en vigueur à partir du registre des rentes de
#' l'année jahr_rr.
#'
#' @description Ce module projette les sommes de rentes selon le droit en vigueur
#' à partir du registre des rentes de l'année l'année jahr_rr à l'aide des
#' facteurs de croissance annuels calculés dans la fonction
#' \code{\link{mod_facteurs_crois_eprc_proj_flex}}. Sa fonction cousine
#' \code{\link{mod_rentensumme_flex}} permet de calculer les sommes des rentes
#' en tenant compte de mesures telles que le relèvement de l'âge de la retraite
#' ou la modification des taux d'anticipation et d'ajournement et trouve son
#' utilité dans \code{\link{wrap_ahv_massnahmen}}.
#'
#' @param PARAM_GLOBAL un dataframe d'une seule ligne, dont nous utilisons les
#'   paramètres suivants:
#'   - `jahr_rr`: Année du registre des rentes analysé
#'   - `jahr_abr`: Année du décompte de la CdC analysée
#'   - `ra_m`: âge légal de départ à la retraite des hommes selon le droit en
#'   vigueur
#'   - `ra_f_2005`: âge légal de départ à la retraite des femmes depuis 2005
#'
#' @param FACTEURS_CROISSANCE_EPRC_PROJETES_FLEX un data frame contenant les
#' facteurs de croissance des EPRC projetes calculé dans la fonction
#' \code{\link{mod_facteurs_crois_eprc_proj_flex}}.
#'
#' @param AHV_ABRECHNUNG data frame contenant le décompte de la CdC présentant
#' les chiffres de l'AVS de 2011 à jahr_abr, cf. fonction
#' \code{\link{mod_input_ahv_abrechnung}}.
#'
#' @param RENTENENTWICKLUNG data frame contenant l'évolution de la rente
#' minimale AVS, cf. fonction \code{\link{mod_rentenentwicklung}}.
#'
#' @param RR_AVS data frame contenant les données des assurés du registre des
#' rentes, cf. \code{\link{mod_input_rr_avs_dataframe}} et
#' create_rr_avs (dinput).
#'
#' @param RENTENZYKLUS data frame contenant les facteurs de
#' correction du niveau des premières rentes calculés dans la fonction
#' \code{\link{mod_rentenzyklus}}.
#'
#' @param list `tidylist`. Elément obligatoire dans tous les modules. Au lieu de
#'   fournir des dataframes au module, il est possible de l'alimenter uniquement
#'   avec une`tidylist` qui contient les tidy dataframes. Tous les datframes
#'   listés doivent être présents dans la tidylist, avec le même nom. De plus,
#'   la `tidylist` peut aussi contenir des dataframes qui ne sont pas utilisés
#'   par le module.
#'
#' @references \href{https://www.bsv.admin.ch/dam/bsv/fr/dokumente/ahv/finanzperspektiven/validierung-modellansatz-ahv.pdf.download.pdf/2018_07_09_definitif_ld_rapport_ofas.pdf}{Rapport de Prof. Dr Laurent Donzé}
#'
#' @return une `tidylist` contenant le data frame suivant:
#' - `RENTENSUMME_AHV_GO`
#' - `RENTENSUMME_AHV_GO_PARAGE`
#'
#' @author [MAS BSV](mailto:sekretariat.mas@bsv.admin.ch)
#'
#' @export

mod_ahv_rentensumme_go <- function(PARAM_GLOBAL,
                                   FACTEURS_CROISSANCE_EPRC_PROJETES_FLEX,
                                   AHV_ABRECHNUNG,
                                   RENTENENTWICKLUNG,
                                   RR_AVS,
                                   RENTENZYKLUS) {
    
  print("Run module: mod_ahv_rentensumme_go")
  
  GA_PROJ <- RR_AVS %>%
    filter(jahr == PARAM_GLOBAL$jahr_rr) %>%
    dplyr::summarize(rs_ref = sum(monatliche_rentensumme) * 12 / 1e6,
                     .by = c("sex", "nat", "dom", "gpr", "alt")) %>%
    right_join(FACTEURS_CROISSANCE_EPRC_PROJETES_FLEX,
               by = c("sex", "nat", "dom", "gpr", "alt"), 
               relationship = "one-to-many") %>%
    filter(jahr >= PARAM_GLOBAL$jahr_rr) %>%
    mutate(alt_c = pmin(PARAM_GLOBAL$rentenzyklus_max_alt + 1, alt)) %>% 
    left_join(RENTENZYKLUS, 
              by = c("sex", "nat", "dom", "gpr", "jahr", "alt_c")) %>%
    # Ersetzung von NA Werten nötig u.a. für Rententypen neben den Altersrenten.
    replace_na(list(cumprod_param_erstrente = 1)) %>%
    group_by(sex, nat, dom, gpr, alt) %>%
    arrange(jahr, .by_group = TRUE) %>%
    mutate(rentensumme =
        rs_ref * cumprod(wachstumsfaktor) * cumprod_param_erstrente) %>%
    ungroup() %>%
    select(sex, nat, dom, gpr, jahr, alt, rentensumme)
  
  # Anbindung historischer Daten.
  RS_H <- RR_AVS %>%
    filter(!is.na(gpr), jahr < PARAM_GLOBAL$jahr_rr) %>%
    group_by(sex, nat, dom, gpr, jahr, alt) %>%
    dplyr::summarize(rentensumme = sum(monatliche_rentensumme) * 12 / 1e6) %>% 
    bind_rows(GA_PROJ)
  
  #-----------Ajustement au budget et dynamisation (Justierung und Rentenanpassung) par année ---

  ABR_RENTENSUMME <- AHV_ABRECHNUNG %>%
    dplyr::select(jahr, rent_tot)

  STATISCH_RS <- RS_H %>%
    group_by(jahr) %>%
    # sommer les rentes pour obtenir des rentes annuelles (enlever les NAs dues aux
    # observations manquantes du RR pour les étrangères de 98 par ex.)
    dplyr::summarize(rentensumme = sum(rentensumme, na.rm = TRUE) * 1e6)

  #
  # STATISCH_RS_ehepaar <- RENTENSUMME_FLEX_1 %>%
  #   group_by(jahr, zv) %>%
  #   summarise(rentensumme = sum(rentensumme, na.rm = TRUE)*1e6)
  #

  just_val <- justierung(
    PARAM_GLOBAL = PARAM_GLOBAL,
    ABRECHNUNG = ABR_RENTENSUMME,
    MODELL = STATISCH_RS)


  STATISCH_RS_ABR <- STATISCH_RS %>%
    left_join(ABR_RENTENSUMME, by = c("jahr")) %>%
    mutate(just_tmp = rent_tot / rentensumme)

  JUST_STATISCH_RS <- STATISCH_RS %>%
    dplyr::select(jahr) %>%
    left_join(STATISCH_RS_ABR, by = c("jahr")) %>%
    mutate(justierung = if_else(jahr <= PARAM_GLOBAL$jahr_abr, just_tmp, just_val)) %>%
    left_join(RENTENENTWICKLUNG, by = "jahr")


  RENTENSUMME_AHV_GO <- JUST_STATISCH_RS %>%
    mutate(rsjustiertstatisch = rentensumme * justierung) %>%
    mutate(rsdynamisch = rsjustiertstatisch * rentenentwicklung) %>%
    dplyr::select(jahr,
      # rsjustiertstatisch,
      rentensumme = rsdynamisch)

  ###creation du tibble par age, sex, dom et nat

  STATISCH_RS_SEX_ALT_DOM_NAT <- RS_H %>%
    filter(gpr == "rvieillesse") %>%
    group_by(jahr, alt, sex, nat, dom) %>%
    # sommer les rentes pour obtenir des rentes annuelles (enlever les NAs dues aux
    # observations manquantes du RR pour les étrangères de 98 par ex.)
    summarise(rentensumme = sum(rentensumme, na.rm = TRUE) * 1e6) %>%
    ungroup() ## important, this will either cause problems or slow it down

  JUST_VAL_SADN <- STATISCH_RS_SEX_ALT_DOM_NAT %>%
    filter(jahr == PARAM_GLOBAL$jahr_abr) %>%
    left_join(STATISCH_RS %>%
                filter(jahr == PARAM_GLOBAL$jahr_abr) %>%
                dplyr::select(jahr, rentensumme_pro_jahr = rentensumme),
              by = "jahr") %>%
    mutate(prop_obs = rentensumme / rentensumme_pro_jahr) %>%
    left_join(ABR_RENTENSUMME, by = "jahr") %>%
    mutate(rent_tot_paragesexdomnat = prop_obs * rent_tot)

  ABRECHNUNG_SADN <- JUST_VAL_SADN %>%
    dplyr::select(jahr, alt, sex, dom, nat, rent_tot_paragesexdomnat)

  JUSTVAL_PARAGESEXDOMNAT <- justierung_paragesexdomnat(
    PARAM_GLOBAL = PARAM_GLOBAL,
    ABRECHNUNG = ABRECHNUNG_SADN,
    MODELL = STATISCH_RS_SEX_ALT_DOM_NAT
  )

  STATISCH_RS_ABR_ALTSEXDOMNAT <- STATISCH_RS_SEX_ALT_DOM_NAT %>%
    left_join(ABRECHNUNG_SADN, by = c("jahr", "alt", "sex", "dom", "nat")) %>%
    mutate(just_tmp = rent_tot_paragesexdomnat / rentensumme)

  JUST_STATISCH_RS_SEX_ALT_DOM_NAT <- STATISCH_RS_SEX_ALT_DOM_NAT %>%
    dplyr::select(jahr, alt, sex, dom, nat) %>%
    left_join(STATISCH_RS_ABR_ALTSEXDOMNAT, by = c("jahr", "alt", "sex", "dom", "nat")) %>%
    # ne pas faire le left_join par année car on a fait un filtre dans justierung_parage()
    left_join(JUSTVAL_PARAGESEXDOMNAT %>%
                dplyr::select(-jahr), by = c("alt", "sex", "dom", "nat")) %>%
    mutate(justierung = if_else(jahr <= PARAM_GLOBAL$jahr_abr, just_tmp, 
                                justval_paragesex)) %>%
    left_join(RENTENENTWICKLUNG, by = "jahr")


  RENTENSUMME_AHV_GO_PARAGESEXDOMNAT <- JUST_STATISCH_RS_SEX_ALT_DOM_NAT %>%
    mutate(rsjustiertstatisch = rentensumme * justierung) %>%
    mutate(rsdynamisch = rsjustiertstatisch * rentenentwicklung) %>%
    dplyr::select(jahr,
                  alt,
                  # rsjustiertstatisch,
                  sex,
                  dom,
                  nat,
                  rentensumme = rsdynamisch
    ) %>%
    filter(!is.na(rentensumme))

  return(list(
      RENTENSUMME_AHV_GO = RENTENSUMME_AHV_GO,
      RENTENSUMME_AHV_GO_PARAGESEXDOMNAT = RENTENSUMME_AHV_GO_PARAGESEXDOMNAT
  ))
}
