#' @title Calcul du nombre de cotisants selon le droit en vigueur.
#'
#' @description Calcul du nombre de cotisants selon le droit en vigueur. Utile
#' pour le questionnaire "Survey on Actuarial Assumptions/Enquête sur les hypothèses
#' actuarielles" du Canada.
#'
#' @param PARAM_GLOBAL  Paramètres globaux
#'
#' @param IK data frame contenant les comptes individuels, voir fonction
#' \code{\link{mod_input_ikregister}}.
#'
#' @param AKTIVE_BEV  Population résidante permanente en ETP (erwbevept)
#'
#' @param BEVOELKERUNG  Population résidante permanente (selon scénario OFS)
#'
#' @param POPULATION_TOT  Population totale (pop. rés. perm., AF, frontaliers, émigrés)
#'
#' @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.
#'
#' @return a `tidylist` containing the following tidy data frames:
#' - `BEITRAEGER_BEV`: nombre de cotisants à l'assurance correspondant à
#' vz par rapport à la population rés. permanente.
#' - `BEITRAEGER_BEV_MW`: nombre de cotisants à l'assurance correspondant
#' à vz (hommes et femmes) par rapport à la population rés. permanente.
#' - `BEITRAEGER_AKTIVE_BEV`: nombre de cotisants à l'assurance correspondant à
#' vz par rapport à la population active en ETP
#' - `BEITRAEGER_AKTIVE_BEV_MW`: nombre de cotisants à l'assurance correspondant
#' à vz (hommes et femmes) par rapport à la population active en ETP
#' - `BEITRAEGER_AF_POPUTOT`: nombre de cotisants à l'assurance facultative si
#' vz == "ahv" par rapport à la population totale (pop. rés. perm., AF,
#' frontaliers, émigrés)
#' - `BEITRAEGER_AF_POPUTOT_MW`: nombre de cotisants à l'assurance facultative
#' si vz == "ahv" (hommes et femmes), par rapport à la population totale (pop.
#' rés. perm., AF, frontaliers, émigrés)
#' - `BEITRAEGER_AGECOT_POPUTOT`: nombre de cotisants par rapport au nombre de personnes
#' en âge de cotiser par année par rapport à la population totale (pop. rés.
#' perm., AF, frontaliers, émigrés)
#' - `BEITRAEGER_AGECOT_POPUTOT_MW`: nombre de cotisants par rapport au nombre
#' de personnes en âge de cotiser par année et selon le sexe par rapport à la population
#' totale (pop. rés. perm., AF, frontaliers, émigrés)
#'
#' @author [MAS BSV](mailto:sekretariat.mas@bsv.admin.ch)
#'
#' @export

mod_ahv_nombre_cotisants <- function(PARAM_GLOBAL,
                                     IK,
                                     BEVOELKERUNG
                                     ) {
    
    print("Run module: mod_ahv_nombre_cotisants")
    
    POPULATION_TOT <- BEVOELKERUNG %>%
        mutate(bevendejahr = bevendejahr, dom = "ch") %>%
        select(jahr, sex, nat, alt, dom, bevendejahr) %>%
        bind_rows(BEVOELKERUNG %>%
                      mutate(bevendejahr = rowSums(select(., auswanderung, frontaliers, saisonniers, assures_facultatifs), na.rm = TRUE), 
                             dom = "au") %>%
                      select(jahr, sex, nat, alt, dom, bevendejahr))

  # Parameter
  vz <- PARAM_GLOBAL$vz

    if ("min_age_cot" %in% colnames(PARAM_GLOBAL)) {
      min_age_cot <- 21
    } else {
      min_age_cot <- PARAM_GLOBAL$min_age_cot
    }
  
  IK_VZ <- IK %>%
    filter(
      vz == PARAM_GLOBAL$vz,
      alt >= 0
    ) %>%
    mutate(
      alt = as.integer(alt),
      alt = if_else(alt <= 98L, alt, 99L)
    )

  # --- 1) Cotisants sur BEVOELKERUNG (POPU. rés. permanente) ----------------------
  D_IK_YEARS_BEV <- IK_VZ %>%
    group_by(jahr, sex, nat, alt) %>%
    summarize(
      spersonen = sum(personen, na.rm = TRUE),
      slohnsumme = sum(einkommen_ik, na.rm = TRUE),
      sbeitrag_bsv = sum(beitrag_bsv, na.rm = TRUE)
    ) %>%
    left_join(BEVOELKERUNG,
      by = c("jahr", "sex", "nat", "alt")
    ) %>%
    group_by(jahr, sex) %>%
    summarise(
      sspersonen = sum(spersonen, na.rm = TRUE),
      sbevendejahr = sum(bevendejahr, na.rm = TRUE),
      sslohnsumme = sum(slohnsumme, na.rm = TRUE),
      beitraegerquote = sspersonen /
        sbevendejahr,
      beitragssatz = sum(sbeitrag_bsv, na.rm = TRUE) /
        sslohnsumme,
      durchschnittseinkommen = sslohnsumme /
        sspersonen
    ) %>%
    rename(
      spersonen = sspersonen,
      bevendejahr = sbevendejahr
    )

  # --- IK Daten fuer Projektion -----------------------------------------------

  D_IK_BEV <- D_IK_YEARS_BEV %>%
    filter(jahr == PARAM_GLOBAL$jahr_ik) %>%
    # filter(alt > 14) %>%  # Anpassung an EPT Scenario
    # filter(alt < 86) %>%  # Anpassung an EPT Scenario
    ungroup() %>%
    dplyr::select(-jahr, -bevendejahr, -spersonen)

  # --- Statische Loesung ------------------------------------------------------

  STATISCH_BS_TMP_BEV <- D_IK_YEARS_BEV %>%
    filter(jahr <= PARAM_GLOBAL$jahr_ik) %>%
    dplyr::select(jahr, sex, spersonen, bevendejahr, beitraegerquote, beitragssatz)


  STATISCH_BS_PR_BEV <- BEVOELKERUNG %>%
    group_by(jahr, sex) %>%
    summarise(bevendejahr = sum(bevendejahr, na.rm = TRUE)) %>%
    filter(jahr > PARAM_GLOBAL$jahr_ik) %>%
    left_join(D_IK_BEV, by = "sex") %>%
    mutate(spersonen = bevendejahr * beitraegerquote) %>%
    dplyr::select(jahr, sex, spersonen, bevendejahr, beitraegerquote, beitragssatz)

  BEITRAEGER_BEV_MW <- full_join(STATISCH_BS_TMP_BEV,
    STATISCH_BS_PR_BEV,
    by = c(
      "jahr", "sex", "spersonen", "bevendejahr",
      "beitraegerquote", "beitragssatz"
    )
  ) %>%
    rename(beitraeger = spersonen)

  BEITRAEGER_BEV <- BEITRAEGER_BEV_MW %>%
    group_by(jahr) %>%
    summarise(
      sum_bevendejahr = sum(bevendejahr, na.rm = TRUE),
      sum_beitraeger = sum(beitraeger, na.rm = TRUE)
    ) %>%
    mutate(beitraegerquote = sum_beitraeger / sum_bevendejahr)

  # --- 2) Cotisants sur AKTIVE_BEV en EPT ------------------------------------
  #-------- TOTAL VZ -----------------------------------------------------------
  D_IK_YEARS <- IK_VZ %>%
    group_by(jahr, sex, nat, alt) %>%
    summarize(
      spersonen = sum(personen, na.rm = TRUE),
      slohnsumme = sum(einkommen_ik, na.rm = TRUE),
      sbeitrag_bsv = sum(beitrag_bsv, na.rm = TRUE)
    ) %>%
    left_join(BEVOELKERUNG,
      by = c("jahr", "sex", "nat", "alt")
    ) %>%
    group_by(jahr, sex) %>%
    summarise(
      sspersonen = sum(spersonen, na.rm = TRUE),
      sbevendejahr = sum(ept, na.rm = TRUE),
      sslohnsumme = sum(slohnsumme, na.rm = TRUE),
      beitraegerquote = sspersonen /
        sbevendejahr,
      beitragssatz = sum(sbeitrag_bsv, na.rm = TRUE) /
        sslohnsumme,
      durchschnittseinkommen = sslohnsumme /
        sspersonen
    ) %>%
    rename(
      spersonen = sspersonen,
      bevendejahr = sbevendejahr
    )

  # --- IK Daten fuer Projektion -----------------------------------------------

  D_IK <- D_IK_YEARS %>%
    filter(jahr == PARAM_GLOBAL$jahr_ik) %>%
    # filter(alt > 14) %>%  # Anpassung an EPT Scenario
    # filter(alt < 86) %>%  # Anpassung an EPT Scenario
    ungroup() %>%
    dplyr::select(-jahr, -bevendejahr, -spersonen)

  # --- Statische Loesung ------------------------------------------------------

  STATISCH_BS_TMP <- D_IK_YEARS %>%
    filter(jahr <= PARAM_GLOBAL$jahr_ik) %>%
    dplyr::select(jahr, sex, spersonen, bevendejahr, beitraegerquote, beitragssatz)


  STATISCH_BS_PR <- BEVOELKERUNG %>%
    group_by(jahr, sex) %>%
    summarise(bevendejahr = sum(ept, na.rm = TRUE)) %>%
    filter(jahr > PARAM_GLOBAL$jahr_ik) %>%
    left_join(D_IK, by = "sex") %>%
    mutate(spersonen = bevendejahr * beitraegerquote) %>%
    dplyr::select(jahr, sex, spersonen, bevendejahr, beitraegerquote, beitragssatz)

  BEITRAEGER_AKTIVE_BEV_MW <- full_join(STATISCH_BS_TMP,
    STATISCH_BS_PR,
    by = c(
      "jahr", "sex", "spersonen", "bevendejahr",
      "beitraegerquote", "beitragssatz"
    )
  ) %>%
    rename(beitraeger = spersonen)

  BEITRAEGER_AKTIVE_BEV <- BEITRAEGER_AKTIVE_BEV_MW %>%
    group_by(jahr) %>%
    summarise(
      sum_bevendejahr = sum(bevendejahr, na.rm = TRUE),
      sum_beitraeger = sum(beitraeger, na.rm = TRUE)
    ) %>%
    mutate(beitraegerquote = sum_beitraeger / sum_bevendejahr)

  # --- 3) Cotisants sur population en âge de cotiser---------------------------
  #-------- TOTAL VZ -----------------------------------------------------------
  POPULATION_TOT_AGECOT <- POPULATION_TOT %>%
    filter(
      alt <= (PARAM_GLOBAL$ra_f_2005 - 1) + 1 * (sex == "m"),
      alt >= min_age_cot
    ) %>%
    group_by(jahr, sex, nat, alt) %>%
    summarise(bevendejahr = sum(bevendejahr, na.rm = TRUE))


  IK_AGECOT <- IK_VZ %>%
    # Exclure les coti des retraités dès 65 et 64 car l'année anniversaire, les
    # cotis ne sont pas formatrices de rente
    filter(
      cgcot != 7,
      alt <= (PARAM_GLOBAL$ra_f_2005 - 1) + 1 * (sex == "m"),
      alt >= min_age_cot
    )

  D_IK_YEARS_AGECOT <- IK_AGECOT %>%
    group_by(jahr, sex, nat, alt) %>%
    summarize(
      spersonen = sum(personen, na.rm = TRUE),
      slohnsumme = sum(einkommen_ik, na.rm = TRUE),
      sbeitrag_bsv = sum(beitrag_bsv, na.rm = TRUE)
    ) %>%
    left_join(POPULATION_TOT_AGECOT,
      by = c("jahr", "sex", "nat", "alt")
    ) %>%
    group_by(jahr, sex) %>%
    summarise(
      sspersonen = sum(spersonen, na.rm = TRUE),
      sbevendejahr = sum(bevendejahr, na.rm = TRUE),
      sslohnsumme = sum(slohnsumme, na.rm = TRUE),
      beitraegerquote = sspersonen /
        sbevendejahr,
      beitragssatz = sum(sbeitrag_bsv, na.rm = TRUE) /
        sslohnsumme,
      durchschnittseinkommen = sslohnsumme /
        sspersonen
    ) %>%
    rename(
      spersonen = sspersonen,
      bevendejahr = sbevendejahr
    )
  # --- IK Daten fuer Projektion -----------------------------------------------

  D_IK_AGECOT <- D_IK_YEARS_AGECOT %>%
    filter(jahr == PARAM_GLOBAL$jahr_ik) %>%
    # filter(alt > 14) %>%  # Anpassung an EPT Scenario
    # filter(alt < 86) %>%  # Anpassung an EPT Scenario
    ungroup() %>%
    dplyr::select(-jahr, -bevendejahr)

  # --- Statische Loesung ------------------------------------------------------
  STATISCH_BS_TMP_AGECOT <- D_IK_YEARS_AGECOT %>%
    filter(jahr <= PARAM_GLOBAL$jahr_ik) %>%
    dplyr::select(jahr, sex, spersonen, bevendejahr, beitraegerquote, beitragssatz)


  STATISCH_BS_PR_AGECOT <- POPULATION_TOT_AGECOT %>%
    group_by(jahr, sex) %>%
    summarise(bevendejahr = sum(bevendejahr, na.rm = TRUE)) %>%
    filter(jahr > PARAM_GLOBAL$jahr_ik) %>%
    left_join(D_IK_AGECOT, by = "sex") %>%
    mutate(spersonen = bevendejahr * beitraegerquote) %>%
    dplyr::select(jahr, sex, spersonen, bevendejahr, beitraegerquote, beitragssatz)

  BEITRAEGER_AGECOT_POPUTOT_MW <- full_join(STATISCH_BS_TMP_AGECOT,
    STATISCH_BS_PR_AGECOT,
    by = c(
      "jahr", "sex", "spersonen", "bevendejahr",
      "beitraegerquote", "beitragssatz"
    )
  ) %>%
    rename(beitraeger = spersonen)

  BEITRAEGER_AGECOT_POPUTOT <- BEITRAEGER_AGECOT_POPUTOT_MW %>%
    group_by(jahr) %>%
    summarise(
      sum_bevendejahr = sum(bevendejahr, na.rm = TRUE),
      sum_beitraeger = sum(beitraeger, na.rm = TRUE)
    ) %>%
    mutate(beitraegerquote = sum_beitraeger / sum_bevendejahr)

  if (vz == "ahv") {
    #----------Assurance facultative----------------------------------------------
    IK_VZ_AF <- IK_VZ %>%
      filter(
        cgcot == 0,
        alt <= (PARAM_GLOBAL$ra_f_2005 - 1) + 1 * (sex == "m"),
        alt >= min_age_cot
      )

    D_IK_YEARS_AF <- IK_VZ_AF %>%
      group_by(jahr, sex, nat, alt) %>%
      summarize(
        spersonen = sum(personen, na.rm = TRUE),
        slohnsumme = sum(einkommen_ik, na.rm = TRUE),
        sbeitrag_bsv = sum(beitrag_bsv, na.rm = TRUE)
      ) %>%
      left_join(POPULATION_TOT_AGECOT,
        by = c("jahr", "sex", "nat", "alt")
      ) %>%
      group_by(jahr, sex) %>%
      summarise(
        sspersonen = sum(spersonen, na.rm = TRUE),
        sbevendejahr = sum(bevendejahr, na.rm = TRUE),
        sslohnsumme = sum(slohnsumme, na.rm = TRUE),
        beitraegerquote = sspersonen /
          sbevendejahr,
        beitragssatz = sum(sbeitrag_bsv, na.rm = TRUE) /
          sslohnsumme,
        durchschnittseinkommen = sslohnsumme /
          sspersonen
      ) %>%
      rename(
        spersonen = sspersonen,
        bevendejahr = sbevendejahr
      )
    # --- IK Daten fuer Projektion -----------------------------------------------

    D_IK_AF <- D_IK_YEARS_AF %>%
      filter(jahr == PARAM_GLOBAL$jahr_ik) %>%
      # filter(alt > 14) %>%  # Anpassung an EPT Scenario
      # filter(alt < 86) %>%  # Anpassung an EPT Scenario
      ungroup() %>%
      dplyr::select(-jahr, -bevendejahr)

    # --- Statische Loesung ------------------------------------------------------
    STATISCH_BS_TMP_AF <- D_IK_YEARS_AF %>%
      filter(jahr <= PARAM_GLOBAL$jahr_ik) %>%
      dplyr::select(jahr, sex, spersonen, bevendejahr, beitraegerquote, beitragssatz)


    STATISCH_BS_PR_AF <- POPULATION_TOT_AGECOT %>%
      group_by(jahr, sex) %>%
      summarise(bevendejahr = sum(bevendejahr, na.rm = TRUE)) %>%
      filter(jahr > PARAM_GLOBAL$jahr_ik) %>%
      left_join(D_IK_AF, by = "sex") %>%
      mutate(spersonen = bevendejahr * beitraegerquote) %>%
      dplyr::select(jahr, sex, spersonen, bevendejahr, beitraegerquote, beitragssatz)

    BEITRAEGER_AF_POPUTOT_MW <- full_join(STATISCH_BS_TMP_AF,
      STATISCH_BS_PR_AF,
      by = c(
        "jahr", "sex", "spersonen", "bevendejahr",
        "beitraegerquote", "beitragssatz"
      )
    ) %>%
      rename(beitraeger = spersonen)

    BEITRAEGER_AF_POPUTOT <- BEITRAEGER_AF_POPUTOT_MW %>%
      group_by(jahr) %>%
      summarise(
        sum_bevendejahr = sum(bevendejahr, na.rm = TRUE),
        sum_beitraeger = sum(beitraeger, na.rm = TRUE)
      ) %>%
      mutate(beitraegerquote = sum_beitraeger / sum_bevendejahr)
  }
  # Output ---------------------------------------------------------------------
  if (vz == "ahv") {
      return(list(
          BEITRAEGER_AF_POPUTOT = BEITRAEGER_AF_POPUTOT,
          BEITRAEGER_AF_POPUTOT_MW = BEITRAEGER_AF_POPUTOT_MW,
          BEITRAEGER_AKTIVE_BEV = BEITRAEGER_AKTIVE_BEV,
          BEITRAEGER_AKTIVE_BEV_MW = BEITRAEGER_AKTIVE_BEV_MW,
          BEITRAEGER_AGECOT_POPUTOT = BEITRAEGER_AGECOT_POPUTOT,
          BEITRAEGER_AGECOT_POPUTOT_MW = BEITRAEGER_AGECOT_POPUTOT_MW,
          BEITRAEGER_BEV = BEITRAEGER_BEV,
          BEITRAEGER_BEV_MW = BEITRAEGER_BEV_MW
      ))
      
  } else {
      return(list(
          BEITRAEGER_AKTIVE_BEV = BEITRAEGER_AKTIVE_BEV,
          BEITRAEGER_AKTIVE_BEV_MW = BEITRAEGER_AKTIVE_BEV_MW,
          BEITRAEGER_AGECOT_POPUTOT = BEITRAEGER_AGECOT_POPUTOT,
          BEITRAEGER_AGECOT_POPUTOT_MW = BEITRAEGER_AGECOT_POPUTOT_MW,
          BEITRAEGER_BEV = BEITRAEGER_BEV,
          BEITRAEGER_BEV_MW = BEITRAEGER_BEV_MW
      ))
  }
}

