spei_spi <- function(data, indicator, 
                     var.list, 
                     pet_method = NULL, 
                     accum, 
                     standardization,
                     stand_refperiod,
                     stand_handleinf,
                     ncores = NULL){
    
    lat_obs <- data$obs$coords$latitude
    lon_obs <- data$obs$coords$longitude
    dates_obs <- data$obs$attrs$Dates
    lat_hcst <- data$hcst$coords$latitude
    lon_hcst <- data$hcst$coords$longitude
    dates_hcst <- data$hcst$attrs$Dates
    lat_fcst <- data$fcst$coords$latitude
    lon_fcst <- data$fcst$coords$longitude
    dates_fcst <- data$fcst$attrs$Dates

    if (indicator == 'spei'){

        # obtain PET
        if (is.null(pet_method)){ # alredy checked (prepare_outputs) that PET exists
                                  # in the data when SPEI is requested without PET method

            data_obs <- data_format_csindicators(data$obs, 
                                                 vars = c('pet', 'prlr'), 
                                                 var.list = var.list, 
                                                 lat = lat_obs, 
                                                 lon = lon_obs, 
                                                 dates = dates_obs)
            if (!is.null(data$hcst)){
                data_hcst <- data_format_csindicators(data$hcst, 
                                                      vars = c('pet', 'prlr'), 
                                                      var.list = var.list, 
                                                      lat = lat_hcst, 
                                                      lon = lon_hcst, 
                                                      dates = dates_hcst)
            } else {
                data_hcst <- NULL
            }
            if (!is.null(data$fcst)){
                data_fcst <- data_format_csindicators(data$fcst, 
                                                      vars = c('pet', 'prlr'), 
                                                      var.list = var.list, 
                                                      lat = lat_fcst, 
                                                      lon = lon_fcst, 
                                                      dates = dates_fcst)
            } else {
                data_fcst <- NULL
            }

        } else {

            if (pet_method == 'hargreaves'){
                vars <- c('tasmax', 'tasmin')
            } else if (pet_method == 'hargreaves_modified'){
                vars <- c('tasmax', 'tasmin', 'prlr')
            } else if (pet_method == 'thornthwaite'){
                vars <- c('tas')
            }
            
            # add prlr to the data for prlr-pet
            if (!('prlr' %in% vars)){vars <- c(vars, 'prlr')} 

            # call CST_PeriodPET from CSIndicators
            data_obs <- data_format_csindicators(data$obs, 
                                                 vars = vars, 
                                                 var.list = var.list, 
                                                 lat = lat_obs, 
                                                 lon = lon_obs, 
                                                 dates = dates_obs)
            data_obs$pet <- CST_PeriodPET(data = data_obs, 
                                          pet_method = pet_method,
                                          ncores = ncores) 

            if (!is.null(data$hcst)){
                data_hcst <- data_format_csindicators(data$hcst, 
                                                      vars = vars, 
                                                      var.list = var.list, 
                                                      lat = lat_hcst, 
                                                      lon = lon_hcst, 
                                                      dates = dates_hcst)
                data_hcst$pet <- CST_PeriodPET(data = data_hcst, 
                                               pet_method = pet_method,
                                               ncores = ncores) 
            }

            if (!is.null(data$fcst)){
                data_fcst <- data_format_csindicators(data$fcst, 
                                                      vars = vars, 
                                                      var.list = var.list, 
                                                      lat = lat_fcst, 
                                                      lon = lon_fcst, 
                                                      dates = dates_fcst)
                data_fcst$pet <- CST_PeriodPET(data = data_fcst, 
                                               pet_method = pet_method,
                                               ncores = ncores) 
            }
        }

        # Obtain difference Precipitation - PET
        data_obs_diff <- data_obs$pr
        data_obs_diff$data <- data_obs$pr$data - data_obs$pet$data

        if (!is.null(data$hcst)){
            data_hcst_diff <- data_hcst$pr
            data_hcst_diff$data <- data_hcst$pr$data - data_hcst$pet$data
        }

        if (!is.null(data$fcst)){
            data_fcst_diff <- data_fcst$pr
            data_fcst_diff$data <- data_fcst$pr$data - data_fcst$pet$data
        }      
    
    } else { # spi (no PET calculation and use of precipitation directly instead of Precipitation - PET)
        
        data_obs <- data_format_csindicators(data$obs, 
                                             vars = 'prlr', 
                                             var.list = var.list, 
                                             lat = lat_obs, 
                                             lon = lon_obs, 
                                             dates = dates_obs)
        data_obs_diff <- data_obs$pr
        
        if (!is.null(data$hcst)){
            data_hcst <- data_format_csindicators(data$hcst, 
                                                  vars = 'prlr', 
                                                  var.list = var.list, 
                                                  lat = lat_hcst, 
                                                  lon = lon_hcst, 
                                                  dates = dates_hcst)
            data_hcst_diff <- data_hcst$pr
        }

        if (!is.null(data$fcst)){
            data_fcst <- data_format_csindicators(data$fcst, 
                                                  vars = 'prlr', 
                                                  var.list = var.list, 
                                                  lat = lat_fcst, 
                                                  lon = lon_fcst, 
                                                  dates = dates_fcst)
            data_fcst_diff <- data_fcst$pr
        }
    }

    #### same workflow for SPEI and SPI starting here
    
    # call CST_PeriodAccumulation function from CSIndicators
    data_obs_accum <- CST_PeriodAccumulation(data = data_obs_diff, 
                                             rollwidth = accum, 
                                             sdate_dim = 'syear',
                                             ncores = ncores)
    if (!is.null(data$hcst)){
        data_hcst_accum <- CST_PeriodAccumulation(data = data_hcst_diff, 
                                                  rollwidth = accum, 
                                                  sdate_dim = 'syear',
                                                  ncores = ncores)
    } else {
        data_hcst_accum <- NULL
    }
    if (!is.null(data$fcst)){
        data_fcst_accum <- CST_PeriodAccumulation(data = data_fcst_diff, 
                                                  rollwidth = accum, 
                                                  sdate_dim = 'syear',
                                                  ncores = ncores)
    } else {
        data_fcst_accum <- NULL
    }

    # call CST_PeriodStandardization function from CSIndicators
    if (standardization){
        data_obs_ind <- CST_PeriodStandardization (data = data_obs_accum, 
                                                    data_cor = NULL, 
                                                    ref_period = stand_refperiod, 
                                                    handle_infinity = stand_handleinf,
                                                    ncores = ncores) 
        
        if (!is.null(data$hcst)){
            data_hcst_ind <- CST_PeriodStandardization (data = data_hcst_accum, 
                                                         data_cor = NULL, 
                                                         ref_period = stand_refperiod, 
                                                         handle_infinity = stand_handleinf,
                                                         ncores = ncores) 
        } else {
            data_hcst_ind <- NULL
        }

        if (!is.null(data$fcst)){
            data_fcst_ind <- CST_PeriodStandardization (data = data_hcst_accum, 
                                                         data_cor = data_fcst_accum, 
                                                         ref_period = stand_refperiod, 
                                                         handle_infinity = stand_handleinf,
                                                         ncores = ncores) 
        } else {
            data_fcst_ind <- NULL
        }
    } else {
        data_obs_ind <- data_obs_accum
        data_hcst_ind <- data_hcst_accum
        data_fcst_ind <- data_fcst_accum
    }

    # result: spi or spei (create list of previous data s2dv_cubes)
    result <- list(data_hcst_ind, data_fcst_ind, data_obs_ind)
    names(result) <- c('hcst', 'fcst', 'obs')

    return(result)
}