#' @title  TUNE TREND SAMPLE RANGE VIA SLIDING WINDOW CROSSVALIDATION
#'
#' @description Ce .
#'
#' @param PARAM_GLOBAL
#'
#' @return une `tidylist` contenant le data frame suivant:
#'   - `AHV`
#'
#' @author [MAS BSV](mailto:sekretariat.mas@bsv.admin.ch)
#'
#' @export


mod_ahv_cv_param <- function(PARAM_GLOBAL,
                             AHV_ABRECHNUNG_DEF,
                             RENTENENTWICKLUNG,
                             PENSION_NM,
                             BFS_SZEN_BASISMODELL,
                             PREISINDEX,
                             A_DAT
                       ) {


    print("Run module: mod_ahv_cv_param")


  # Projection interval *including* the current year.
  # pint  <- c(PARAM_GLOBAL$jahr_abr: PARAM_GLOBAL$jahr_ende_basismodell)
  #
  # # Speed up computations through masking of functions by C++ equivalents and
  # # multithreading.
  # collapse::set_collapse(mask = "all", nthreads = 4)
  #
  # # Pooling function within k-step error estimates.
  # err = function(pred, obs) abs(pred - obs)
  #
  # # Admissible value range for number of trend estimation points during CV.
  # pr <- list("tr" = 4:6, "tot" = 4:6)
  #
  # mp <- RENTENENTWICKLUNG %>%
  #   mutate(mp = 12 * minimalrente)  %>%
  #   select(jahr, mp)
  #
  # out <- 10
  #
  # # Historical inflation data.
  # inflation <-
  #   PREISINDEX %>%
  #   select(year = jahr, infl = lik_basis_1977)
  #
  # # write.table(a_dat, "~/data/appl-wb/20_staff/dga/a_dat_check.csv", row.names = FALSE, sep = ";")
  #
  # # Calculate breakpoint for starting year selection. The initial year 2005 has been chosen
  # # to avoid contaminations due to the reference age increases for women along the 10th
  # # AHV reform.
  # zas <- AHV_ABRECHNUNG_DEF %>%
  #   select(jahr, exp_tot = aus_tot) %>%
  #   mutate(exp_tot = exp_tot * 1e6)  %>%
  #   filter(jahr <= first(pint))
  #
  # bp <-
  #   max(
  #     (zas %>% left_join(mp, by = "jahr") %>%
  #        na.omit() %>%
  #        mutate(exp_tot = exp_tot / mp) %>%
  #        filter(jahr >= 2005) %>%
  #        strucchange::breakpoints(diff(exp_tot) ~ 1, data = ., breaks = 1))$breakpoints,
  #     0, na.rm = TRUE)
  #
  # # Restrict to viable training data.
  # t_dat <- A_DAT %>%
  #   filter(jahr <= PARAM_GLOBAL$jahr_abr & jahr >= 2005 + (bp - 1))
  #
  # # Number of estimation points to consider for trend extrapolation.
  # ran <-
  #   expand_grid(nau = pr[["tr"]], mau = pr[["tr"]],
  #               mch = pr[["tr"]], tot = pr[["tot"]])
  #
  # # List to store forecast performances of respective 'range' fits.
  # el <- list()
  #
  # # Constant to harmonize the number of training windows across parameter sets.
  # tmax <- as.numeric(lapply(pr, max)) %>% max
  #
  # # Cross-validation loop over trend ranges, groups and time windows.
  # for (z in 1:nrow(ran)) {
  #
  #   rant <-
  #     dplyr::slice(ran, z)
  #
  #   eval <- list()
  #
  #   for (w in 1:(length(unique(t_dat$jahr)) - (tmax + out) + 1)) {
  #
  #     rl <- list()
  #
  #     for (i in c("m", "f")) {
  #       for (j in c("ch", "au")) {
  #         for (k in c("alt", "kin", "wai", "wit")) {
  #
  #           temp <- t_dat %>%
  #             filter(sex == i, dom == j, type == k) %>%
  #             dplyr::slice(w : (w + (tmax + out) - 1))
  #
  #           # Impute native average pension level.
  #           ind_m <- (tmax + 1):(tmax + out)
  #           temp$m[ind_m] <- NA
  #
  #           if (j == "ch") {
  #
  #             fit_m <-
  #               lm(I(diff(m)) ~ 1, dplyr::slice(temp, (tmax - rant$mch + 1):tmax)) %>%
  #               predict(dplyr::slice(temp, ind_m))
  #
  #             temp$m[ind_m] <-
  #               pmax(0, last(na.omit(temp)$m) + cumsum(fit_m))
  #           }
  #
  #           if (j == "au") {
  #
  #             # Impute foreign average pension level.
  #             fit_m <-
  #               lm(I(diff(m)) ~ 1, dplyr::slice(temp, (tmax - rant$mau + 1):tmax)) %>%
  #               predict(dplyr::slice(temp, ind_m))
  #
  #             temp$m[ind_m] <-
  #               pmin(2, pmax(0, last(na.omit(temp)$m) + cumsum(fit_m)))
  #
  #             # Impute foreign pension count.
  #             temp$n[(tmax + 1):(tmax + out)] <- NA
  #             ind_n <- which(is.na(temp$n))
  #
  #             fit_n <-
  #              lm(I(D(n))  ~ 1, dplyr::slice(temp, (tmax - rant$nau + 1):tmax)) %>%
  #               predict(dplyr::slice(temp, ind_n))
  #
  #             temp$n[ind_n] <-
  #               pmax(0, last(na.omit(temp)$n) + cumsum(fit_n))
  #           }
  #
  #           rl[[paste0(i, j, k)]] <- temp
  #         }
  #       }
  #     }
  #
  #     split <-
  #       rsample::initial_time_split(
  #         bind_rows(rl) %>%
  #           dplyr::summarise(m = weighted.mean(m, n), n = sum(n), .by = c("jahr", "mp")) %>%
  #           dplyr::slice((tmax - rant$tot + 1):(tmax + out)) %>%
  #           left_join(zas, by = "jahr") %>%
  #           rename(exp_p = exp_tot) %>%
  #           mutate(d_nmmp = D(n * m * mp)),
  #         prop = rant$tot / (rant$tot + out))
  #
  #     fit <-
  #       lm(I((D(exp_p))) ~ 0 + d_nmmp, data = rsample::training(split)) %>%
  #       predict(rsample::testing(split)) %>%
  #       cumsum()
  #
  #     temp <-
  #       tibble(k    = 1:out,
  #              obs  = rsample::testing(split)$exp_p[1:out],
  #              pred = (last(rsample::training(split)$exp_p) + fit)[1:out]) %>%
  #       mutate(err = err(pred, obs),
  #              ran = rep(paste0(rant, collapse = ""), nrow(.)))
  #
  #     # Discount forecast errors.
  #     d <- inflation %>%
  #       filter(year %in% rsample::testing(split)$jahr) %>%
  #       mutate(k = 1:out, df = cumprod(1 / (infl / first(infl) + .02))) %>%
  #       select(k, df)
  #
  #     temp %<>%
  #       left_join(d, by = "k") %>%
  #       mutate(err = err * df) %>%
  #       select(- df)
  #
  #     eval[[w]] <- temp
  #   }
  #
  #   # Save run for specific 'range' combination.
  #   el[[z]] <- eval
  # }
  #
  # # Pooling function across pooled k-step error estimates.
  # glo = function(x) mean(x)
  #
  # # Arrange and aggregate k-step errors of different trend estimation sample
  # # sizes, and select the 'range' combination with minimal average error.
  # RANGE <-
  #   max(t_dat$jahr) + 1 -
  #   dplyr::slice(ran,
  #                bind_rows(el) %>%
  #                  dplyr::summarize(err = glo(err), .by = c("ran", "k")) %>%
  #                  pivot_wider(names_from = ran, values_from = err) %>%
  #                  dplyr::summarize(across(- 1, glo)) %>%
  #                  which.min()) %>% as.numeric()
  #
  # set_collapse(mask = NULL)
  #
  # RANGE <- as_tibble(RANGE)

  RANGE <- tibble(value = c(2021, 2019, 2019, 2021))

  # --- Output ----------------------------------------------------------------

  return(RANGE = RANGE)
}
