#'Function to create all multi system/reference scorecards
#' 
#'@description Scorecards function to create scorecard tables for multiple systems
#' and references (types 9 to 12).
#'@param input_data is an array of spatially aggregated metrics containing the
#'   following dimensions; system, reference, metric, time, sdate, region.
#'@param system a vector of character strings defining the systems following the
#'   archive.yml format from verification suite 
#'@param reference a vector of character strings defining the references 
#'  following the archive.yml format from verification suite 
#'@param var a character string following the format from 
#'  variable-dictionary.yml from verification suite 
#'@param start.year a numeric indicating the start year of the reference period
#'@param end.year a numeric indicating the end year of the reference period
#'@param start.date a vector of character strings indicating the start months
#'@param forecast.month a vector of numeric indicating the forecast months
#'@param region.names a vector of character strings containing names of the 
#'  regions corresponding to the input data
#'@param metrics a vector of character strings containing the metrics.
#'@param table.label a character string containing additional information to 
#'  include in the scorecard title
#'@param fileout.label a character string containing additional information to 
#'  include in the output png file when saving the scorecard.
#'@param output.path a path of the location to save the scorecard plots.
#'
#'@return
#' This function returns 4 scorecard images for each region requested, the 
#' images are saved in the directory output.path.

#'@example
#' scorecard_multi <- ScorecardsMulti(data = aggregated_metrics,
#'                                    system.name = c('ECMWF-SEAS5','DWD-GFCS2.1'),
#'                                    reference.name = 'ERA5',
#'                                    var = 'tas', 
#'                                    start.year = 1993,
#'                                    end.year = 2016,
#'                                    start.months = 1:12,
#'                                    forecast.months = 1:6,
#'                                    region.names = c('Tropics', 'Extra-tropical NH', 'Extra-tropical SH')
#'                                    metrics = c('mean_bias', 'enscorr', 'rpss','crpss', 'enssprerr'),
#'                                    table.label = '(Interpolation = to system, Aggregation level = skill, Cross-validation = terciles)',
#'                                    fileout.label = '_crossval-terciles_agg-skill',
#'                                    output.path = '/esarchive/scratch/nmilders/scorecards_images/testing'
#'                                    )


ScorecardsMulti <- function(data,
                            system,
                            reference,
                            var,
                            start.year,
                            end.year,
                            start.months,
                            forecast.months,
                            region.names,
                            metrics,
                            table.label,
                            fileout.label,
                            output.path){

  ## Checks to apply:
  # first dimension in aggregated_metrics is system and second dimension is reference
  # either multi-system and one reference, or multi-reference and one system
  
  ## Initial checks
  if (is.null(table.label)){
    table.label <- ""
  }
  if (is.null(fileout.label)){
    fileout.label <- ""
  }
  
  ## Make sure input_data is in correct order for using in functions:
  data_order <- c('system','reference','metric','time','sdate','region')
  data <- Reorder(data, data_order)
  
  ## Identify metrics loaded
  metrics_loaded <-  attributes(data)$metrics
  
  ## Select only the metrics to visualize from data
  input_data <- Subset(data, along = 'metric', indices = match(metrics, metrics_loaded))
  attributes(input_data)$metrics <- metrics
  
  ## Transform data for scorecards by forecast month (types 11 & 12)
  transformed_data <- SCTransform(data = input_data,
                                  sdate_dim = 'sdate',
                                  ftime_dim = 'time')
  
  ## Load configuration files
  sys_dict <- read_yaml("/esarchive/scratch/nmilders/gitlab/git_clones/s2s-suite/conf/archive.yml")$esarchive
  var_dict <- read_yaml("/esarchive/scratch/nmilders/gitlab/git_clones/csscorecards/inst/config/variable-dictionary.yml")$vars

  ## Get scorecards table display names from configuration files
  var.name <- var_dict[[var]]$long_name
  var.units <- var_dict[[var]]$units

  system.name <-  NULL
  reference.name <- NULL
  
  for(sys in 1:length(system)){
    system.name1 <- sys_dict$System[[system[sys]]]$name 
    system.name <- c(system.name, system.name1)
  }
  for(ref in 1:length(length)){
    reference.name1 <- sys_dict$Reference[[reference[ref]]]$name
    reference.name <- c(reference.name, reference.name1)
  }
  
  ## Get metric long names
  metric.names.list <- .met_names(metrics, var.units)
  
  ## format the metric names as character instead of list
  for(met in metrics){
    if(met == metrics[1]){
      metric.names <- metric.names.list[[met]] 
    } else {
      metric.names <- c(metric.names, metric.names.list[[met]])
    }
  }
  
  ## Define parameters depending on Multi-system or Multi-reference
  if(length(system) > 1 && length(reference) == 1){
    model <- 'system'
    table.model.name <- 'System'
    model.name <- system.name
    eval.label <- 'Ref'
    eval.name <- reference.name
    eval.filename <- reference
  } else if(length(system) == 1 && length(reference) > 1){
    model <- 'reference'
    table.model.name <- 'Reference'
    model.name <- reference.name
    eval.label <- 'Sys'
    eval.name <- system.name
    eval.filename <- system
  } else {stop('Not multi system or multi reference')}
  
  ## Define table colors 
  palette <- c('#2D004B', '#542789', '#8073AC', '#B2ABD2', '#D8DAEB', '#FEE0B6', '#FDB863', '#E08214', '#B35806', '#7F3B08')
  colorunder <- "#04040E"
  colorsup <- "#730C04"
  
  ## Legend lower limit color
  legend.col.inf <- .legend_col_inf(metrics, colorunder)
  legend.col.inf <- legend.col.inf[metrics]
  
  ## Legend upper limit color
  legend.col.sup <- .legend_col_sup(metrics, colorsup)
  legend.col.sup <- legend.col.sup[metrics]
  
  ## Legend inputs
  plot.legend = TRUE
  label.scale = 1.4
  legend.width = 555
  legend.height = 50
  
  ## Data display inputs
  round.decimal = 2
  font.size = 1.1
  
  legend.white.space  <- col1.width <- col2.width <- NULL ## Use default values of function

  ## Loop over region 
  for(reg in 1:length(region.names)){
    
    breaks_bias <- NULL
    
    ## Find position of mean bias metric to calculate breaks
    if ('mean_bias' %in% metrics) {
      pos_bias <- which(metrics == 'mean_bias')
      if(var == 'psl'){
        data[,,pos_bias,,,] <- data[,,pos_bias,,,]/100 ## temporary
      }
      breaks_bias <- .SCBiasBreaks(Subset(data, along = c('metric','region'), 
                                          indices = list(pos_bias,reg)))
    }
    
    ## Define breaks for each metric based of metric position:
    legend.breaks <- .met_breaks(metrics, breaks_bias)
    
    ## Define scorecard titles
    table.title <- paste0(var.name, ".  Region: ", region.names[reg], " ", table.label)
    table.subtitle <- paste0("(", eval.label, ": ", eval.name, " ", start.year, "-", end.year, ")")
    
    
      #### Scorecard_type 9 ####
      ## (no transformation or reorder)
      fileout <- .Filename(model = model, eval.name = eval.filename, var = var, 
                           start.year = start.year, end.year = end.year, scorecard.type = 9, 
                           region =  sub(" ", "-", region.names[reg]),
                           fileout.label = fileout.label, output.path = output.path)
    if(model == 'system'){
      data_sc_9 <- Subset(input_data, c('reference','region'), list(1, reg), drop = 'selected')
    } else if(model == 'reference'){
      data_sc_9 <- Subset(input_data, c('system','region'), list(1, reg), drop = 'selected')
    }
      SCPlotScorecard(data = data_sc_9,
                      row.dim = model,
                      subrow.dim = 'time',
                      col.dim = 'metric',
                      subcol.dim = 'sdate',
                      legend.dim = 'metric',
                      row.names = model.name,
                      subrow.names = forecast.months,
                      col.names = metric.names,
                      subcol.names = month.abb[as.numeric(start.months)],
                      table.title = table.title,
                      table.subtitle = table.subtitle,
                      row.title = table.model.name,
                      subrow.title = 'Forecast Month',
                      col.title = 'Start date',
                      legend.breaks = legend.breaks,
                      plot.legend = plot.legend,
                      label.scale = label.scale,
                      legend.width = legend.width,
                      legend.height = legend.height,
                      palette = palette,
                      colorunder = legend.col.inf,
                      colorsup = legend.col.sup,
                      round.decimal = round.decimal,
                      font.size = font.size,
                      legend.white.space = legend.white.space, 
                      col1.width = 4,
                      col2.width = col2.width,
                      fileout = fileout)
      
      
      #### Scorecard_type 10 ####
      ## (reorder only) 
      fileout <- .Filename(model = model, eval.name = eval.filename, var = var, 
                           start.year = start.year, end.year = end.year, scorecard.type = 10, 
                           region =  sub(" ", "-", region.names[reg]),
                           fileout.label = fileout.label, output.path = output.path)
      new_order <- c('system', 'reference', 'metric', 'region','sdate', 'time')
      if(model == 'system'){
        data_sc_10 <- Subset(Reorder(input_data, new_order), c('reference','region'), list(1, reg), drop = 'selected')
      } else if(model == 'reference'){
        data_sc_10 <- Subset(Reorder(input_data, new_order), c('system','region'), list(1, reg), drop = 'selected')
      }
      SCPlotScorecard(data = data_sc_10,
                      row.dim = 'time',
                      subrow.dim = model,
                      col.dim = 'metric',
                      subcol.dim = 'sdate',
                      legend.dim = 'metric',
                      row.names = forecast.months,
                      subrow.names = model.name,
                      col.names = metric.names,
                      subcol.names = month.abb[as.numeric(start.months)],
                      table.title = table.title,
                      table.subtitle = table.subtitle,
                      row.title = 'Forecast month',
                      subrow.title = table.model.name,
                      col.title = 'Start date',
                      legend.breaks = legend.breaks,
                      plot.legend = plot.legend,
                      label.scale = label.scale,
                      legend.width = legend.width,
                      legend.height = legend.height,
                      palette = palette,
                      colorunder = legend.col.inf,
                      colorsup = legend.col.sup,
                      round.decimal = round.decimal,
                      font.size = font.size,
                      legend.white.space = legend.white.space, 
                      col1.width = col1.width,
                      col2.width = 4,
                      fileout = fileout)
      
  
      #### Scorecard_type 11 ####
      ## (transformation only)
      fileout <- .Filename(model = model, eval.name = eval.filename, var = var, 
                           start.year = start.year, end.year = end.year, scorecard.type = 11, 
                           region =  sub(" ", "-", region.names[reg]),
                           fileout.label = fileout.label, output.path = output.path)
      if(model == 'system'){
        data_sc_11 <- Subset(transformed_data, c('reference','region'), list(1, reg), drop = 'selected')
      } else if(model == 'reference'){
        data_sc_11 <- Subset(transformed_data, c('system','region'), list(1, reg), drop = 'selected')
      }
      SCPlotScorecard(data = data_sc_11,
                      row.dim = model,
                      subrow.dim = 'time',
                      col.dim = 'metric',
                      subcol.dim = 'sdate',
                      legend.dim = 'metric',
                      row.names = model.name,
                      subrow.names = forecast.months,
                      col.names = metric.names,
                      subcol.names = month.abb[as.numeric(start.months)],
                      table.title = table.title,
                      table.subtitle = table.subtitle,
                      row.title = table.model.name,
                      subrow.title = 'Forecast Month',
                      col.title = 'Target month',
                      legend.breaks = legend.breaks,
                      plot.legend = plot.legend,
                      label.scale = label.scale,
                      legend.width = legend.width,
                      legend.height = legend.height,
                      palette = palette,
                      colorunder = legend.col.inf,
                      colorsup = legend.col.sup,
                      round.decimal = round.decimal,
                      font.size = font.size,
                      legend.white.space = legend.white.space, 
                      col1.width = 4,
                      col2.width = col2.width,
                      fileout = fileout)
      
      
      #### Scorecard_type 12 ####
      ## (transformation and reorder)
      fileout <- .Filename(model = model, eval.name = eval.filename, var = var, 
                           start.year = start.year, end.year = end.year, scorecard.type = 12, 
                           region =  sub(" ", "-", region.names[reg]),
                           fileout.label = fileout.label, output.path = output.path)
      new_order <- c('system', 'reference', 'metric', 'region','sdate', 'time')
      if(model == 'system'){
        data_sc_12 <- Subset(Reorder(transformed_data, new_order), c('reference','region'), list(1, reg), drop = 'selected')
      } else if(model == 'reference'){
        data_sc_12 <- Subset(Reorder(transformed_data, new_order), c('system','region'), list(1, reg), drop = 'selected')
      }
      SCPlotScorecard(data = data_sc_12,
                      row.dim = 'time',
                      subrow.dim = model,
                      col.dim = 'metric',
                      subcol.dim = 'sdate',
                      legend.dim = 'metric',
                      row.names = forecast.months,
                      subrow.names = model.name,
                      col.names = metric.names,
                      subcol.names = month.abb[as.numeric(start.months)],
                      table.title = table.title,
                      table.subtitle = table.subtitle,
                      row.title = 'Forecast Month',
                      subrow.title = table.model.name,
                      col.title = 'Target month',
                      legend.breaks = legend.breaks,
                      plot.legend = plot.legend,
                      label.scale = label.scale,
                      legend.width = legend.width,
                      legend.height = legend.height,
                      palette = palette,
                      colorunder = legend.col.inf,
                      colorsup = legend.col.sup,
                      round.decimal = round.decimal,
                      font.size = font.size,
                      legend.white.space = legend.white.space, 
                      col1.width = col1.width,
                      col2.width = 4,
                      fileout = fileout)

  } ## close loop on region  
      
  print("All multi scorecard plots created")
  
} ## close function      

