# Load functions
source("modules/Indicators/R/data_format_csindicators.R")
source("modules/Indicators/R/spei_spi.R")
source("modules/Indicators/R/threshold.R")
source("modules/Indicators/R/data_transformation.R")
source("modules/Indicators/R/malaria_or_ticks.R")
source("modules/Indicators/R/percentile_threshold.R")
source("modules/Indicators/R/absolute_threshold.R")
source("modules/Indicators/R/heat_index.R")

source("modules/Indicators/R/tmp/CSIndicators_CST_PeriodStandardization.R") #### tmp!!!
source("modules/Indicators/R/tmp/CST_Bind.R") #### tmp!!!


Indicators <- function(recipe, data) {
  var.list <- strsplit(recipe$Analysis$Variables$name, ", ")[[1]]
  ncores <- recipe$Analysis$ncores
  
  # SPEI
  if (!is.null(recipe$Analysis$Workflow$Indicators$SPEI$return_spei)) {
    if (recipe$Analysis$Workflow$Indicators$SPEI$return_spei) {
      # read recipe parameters
      pet_method <- recipe$Analysis$Workflow$Indicators$SPEI$PET_method
      if (pet_method == "none") {
        pet_method <- NULL
      }
      spei_accum <- recipe$Analysis$Workflow$Indicators$SPEI$Nmonths_accum
      spei_standardization <- recipe$Analysis$Workflow$Indicators$SPEI$standardization
      spei_stand_refperiod <- recipe$Analysis$Workflow$Indicators$SPEI$standardization_ref_period
      if (is.null(spei_stand_refperiod)) {
        spei_stand_refperiod <- c(recipe$Analysis$Time$hcst_start, recipe$Analysis$Time$hcst_end)
      }
      spei_stand_refperiod <- as.numeric(spei_stand_refperiod)
      spei_stand_handleinf <- recipe$Analysis$Workflow$Indicators$SPEI$standardization_handle_infinity
      
      # call spei_spi function from modules/Indicators/R
      result_spei <- spei_spi(
        data = data,
        indicator = "spei",
        var.list = var.list,
        pet_method = pet_method,
        accum = spei_accum,
        standardization = spei_standardization,
        stand_refperiod = spei_stand_refperiod,
        stand_handleinf = spei_stand_handleinf,
        ncores = ncores
      )
    }
  }
  
  # SPI
  if (!is.null(recipe$Analysis$Workflow$Indicators$SPI$return_spi)) {
    if (recipe$Analysis$Workflow$Indicators$SPI$return_spi) {
      # read recipe parameters
      spi_accum <- recipe$Analysis$Workflow$Indicators$SPI$Nmonths_accum
      spi_standardization <- recipe$Analysis$Workflow$Indicators$SPI$standardization
      spi_stand_refperiod <- recipe$Analysis$Workflow$Indicators$SPI$standardization_ref_period
      if (is.null(spi_stand_refperiod)) {
        spi_stand_refperiod <- c(recipe$Analysis$Time$hcst_start, recipe$Analysis$Time$hcst_end)
      }
      spi_stand_refperiod <- as.numeric(spi_stand_refperiod)
      spi_stand_handleinf <- recipe$Analysis$Workflow$Indicators$SPI$standardization_handle_infinity
      
      # call spei_spi function from modules/Indicators/R
      result_spi <- spei_spi(
        data = data,
        indicator = "spi",
        var.list = var.list,
        pet_method = NULL,
        accum = spi_accum,
        standardization = spi_standardization,
        stand_refperiod = spi_stand_refperiod,
        stand_handleinf = spi_stand_handleinf,
        ncores = ncores
      )
    }
  }
  
  # Threshold based:
  if (!is.null(recipe$Analysis$Workflow$Indicators$SelectedThreshold$return_thresholdbased)) {
    if (recipe$Analysis$Workflow$Indicators$SelectedThreshold$return_thresholdbased) {
      if(!is.null(recipe$Analysis$Workflow$Indicators$SelectedThreshold$threshold)){
        thrs <- recipe$Analysis$Workflow$Indicators$SelectedThreshold$threshold
        return.values <- recipe$Analysis$Workflow$Indicators$SelectedThreshold$returnValues
        result_threshold <- threshold(data, thrs, var.list, return.values)
      }
    }
  }
  
  # Percentile Threshold:
  if(!is.null(recipe$Analysis$Workflow$Indicators$PercentileThreshold$return_percentilebased)) {
    if (recipe$Analysis$Workflow$Indicators$PercentileThreshold$return_percentilebased) {
      percentile <- recipe$Analysis$Workflow$Indicators$PercentileThreshold$percentile
      operator <- recipe$Analysis$Workflow$Indicators$PercentileThreshold$operator
      spell <- recipe$Analysis$Workflow$Indicators$PercentileThreshold$spell
      return.percent <- recipe$Analysis$Workflow$Indicators$PercentileThreshold$returnPercentageDays
      percentile.threshold.name <- recipe$Analysis$Workflow$Indicators$PercentileThreshold$name
      
      if(recipe$Analysis$Horizon == "seasonal"){
      ftimes <- recipe$Analysis$Time$ftime_min : recipe$Analysis$Time$ftime_max
      sdate <- as.numeric(substr(recipe$Analysis$Time$sdate, 1, 2))
      forecast_periods <- (sdate -1 + ftimes - 1) %% 12 + 1
      } else if (recipe$Analysis$Horizon == "subseasonal"){
        forecast_periods <- NULL
      }
      result_percentile <- percentile_threshold(data, percentile, operator, spell,
                                                forecast_periods, return.percent, 
                                                indicator = percentile.threshold.name, 
                                                ncores)
    }
  }
  
  # Absolute Threshold:
  if(!is.null(recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$return_absolutebased)) {
    if (recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$return_absolutebased) {
      threshold <- recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$threshold
      operator <- recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$operator
      spell <- recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$spell
      return.percent <- recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$returnPercentageDays
      absolute.threshold.name <- recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$name
      
      if(recipe$Analysis$Horizon == "seasonal"){
        ftimes <- recipe$Analysis$Time$ftime_min : recipe$Analysis$Time$ftime_max
        sdate <- as.numeric(substr(recipe$Analysis$Time$sdate, 1, 2))
        forecast_periods <- (sdate -1 + ftimes - 1) %% 12 + 1
      } else if (recipe$Analysis$Horizon == "subseasonal"){
        forecast_periods <- NULL
      }
      result_absolute_thrs <- absolute_threshold(data, threshold, operator, spell, 
                                                 forecast_periods, return.percent, 
                                                 indicator = absolute.threshold.name, ncores)
    }
  }
  
  if (!is.null(recipe$Analysis$Workflow$Indicators$HeatIndex$return_heatindex)) {
    if (recipe$Analysis$Workflow$Indicators$HeatIndex$return_heatindex) {
        # return.values <- recipe$Analysis$Workflow$Indicators$HeatIndex$returnValues
        result_heatindex <- heat_index(data)
      }
    }
  
  # Malaria indicator:
  if (!is.null(recipe$Analysis$Workflow$Indicators$Malaria$return_climate_suitability)) {
    if (recipe$Analysis$Workflow$Indicators$Malaria$return_climate_suitability) {
      result_malaria <- list()
      for (ssp in recipe$Analysis$Workflow$Indicators$Malaria$ssp) {
        result_malaria[[ssp]] <- malaria_or_ticks(data, var.list, ssp)
      }
    }
  }
  # Tick-borne disease indicator:
  if (!is.null(recipe$Analysis$Workflow$Indicators$Ticks$return_climate_suitability)) {
    if (recipe$Analysis$Workflow$Indicators$Ticks$return_climate_suitability) {
      result_ticks <- list()
      for (ssp in recipe$Analysis$Workflow$Indicators$Ticks$ssp) {
        result_ticks[[ssp]] <- malaria_or_ticks(data, var.list, ssp)
      }
    }
  }
  
  indicators.list <- c(
    "SPEI" = "result_spei",
    "SPI" = "result_spi",
    "ThresholdBased" = "result_threshold",
    "Malaria" = "result_malaria",
    "Ticks" = "result_ticks",
    "HeatIndex" = "result_heatindex")
  
  ## Insert indicators with variable names
  if(!is.null(recipe$Analysis$Workflow$Indicators$PercentileThreshold$return_percentilebased)) {
    if (recipe$Analysis$Workflow$Indicators$PercentileThreshold$return_percentilebased){
      indicators.list <- c(indicators.list, setNames("result_percentile", percentile.threshold.name))
    }
  }
  if(!is.null(recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$return_absolutebased)) {
    if (recipe$Analysis$Workflow$Indicators$AbsoluteThreshold$return_absolutebased){
      indicators.list <- c(indicators.list, setNames("result_absolute_thrs", absolute.threshold.name))
    }
  }
  
  result <- list()
  for (ind in indicators.list) {
    if (exists(ind)) {
      result[[names(indicators.list)[which(indicators.list == ind)]]] <- eval(parse(text = ind))
    }
  }
  
  return(result)
}
