#' @title Provenance Construction for DatasetSubset
#' @description Generate provenance for a DatasetSubset within the SUNSET framework.
#' @param recipe Configuration file specifying parameters.
#' @param data s2dv_cube object generated by SUNSET's Loading.R function.
#' @param graph igraph object representing the provenance graph.
#' @return A list containing the updated graph and the name of the parent node.
#' @details This function constructs provenance information for a DatasetSubset within SUNSET. 
#'          It adds nodes and edges to the provided graph to represent various aspects of the DatasetSubset, 
#'          including variables, spatial extents, realizations, and temporal periods.
#' @references https://earth.bsc.es/gitlab/es/sunset/-/tree/Dev-Provenance?ref_type=heads 
#'             Documentation for SUNSET's provenance generation.
#' @references This function is based on the semantics outlined in the Datasource ontology within 
#'             the Metaclip Framework (available at \url{http://www.metaclip.org/}).
#' @import igraph

prov_datasetsubset <- function(recipe, data, graph) {

  #First metadata definitions
  ref.name <- recipe$Analysis$Datasets$Reference$name #Reference name
  exp.name <- recipe$Analysis$Datasets$System$name #System name
  archive <- get_archive(recipe)
  reference_descrip <- archive$Reference[[ref.name]]
  exp_descrip <- archive$System[[exp.name]]

  #Extract the type from previous nodename
  parent.node <- graph$parentnodename
  type <- strsplit(parent.node, "_")[[1]][[2]]

  #Add DatasetSubset node
  graph <- graph$graph
  datasetsubset.nodename <- paste0("DatasetSubset_", type)
  graph <- add_vertices(graph,
                        nv = 1,
                        name = datasetsubset.nodename,
                        label = "DatasetSubset",
                        className = "ds:DatasetSubset")

  # Link with existing parent node
  graph <- add_edges(graph,
                     c(getNodeIndexbyName(graph, parent.node),
                       getNodeIndexbyName(graph, datasetsubset.nodename)),
                     label = paste0("ds:hadDatasetSubset"))

  #Add files directory
  directory.nodename <- paste0("Location_", "Datasubset_", type)

  #Extract all directories
  source_files <- data[[type]]$attr$source_files
  directory <- paste(source_files, collapse = " ")

  graph <- add_vertices(graph,
                        nv = 1,
                        name = directory.nodename,
                        label = paste0(type, " ", "directories"),
                        className = "prov:Location",
                        attr = list("prov:value" = directory,
                                    "dc:description" = "Barcelona 
                                     Supercommputing Center Earth 
                                     Science Department
                                     local repository. More information 
                                     about the datasets can be found 
                                     at SUNSETs
                                     configuration files.",
                                    "prov:atTime" = as.character(Sys.time())))

  graph <- add_edges(graph,
                     c(getNodeIndexbyName(graph, datasetsubset.nodename),
                       getNodeIndexbyName(graph, directory.nodename)),
                     label = "prov:atLocation")

  # Add variable metadata
  var <- recipe$Analysis$Variables$name
  var.freq <- recipe$Analysis$Variables$freq #Var frequency
  #Extract metadata about the variables from the conf file
  var_descrip <- read_yaml("conf/variable-dictionary.yml")
  units <- var_descrip$vars[[var]]$units #Units
  long.name <- var_descrip$vars[[var]]$long_name #Long name
  var.nodename <- paste0("Variable_", type)
  graph <- add_vertices(graph,
                        nv = 1,
                        name = var.nodename,
                        label = var,
                        className = "ds:Variable",
                        description = "Encode metadata of a Variable",
                        attr = list("ds:withUnits" = units,
                                    "ds:hasLongName" = long.name,
                                    "ds:TemporalResolution" = var.freq))
  graph <- add_edges(graph,
                     c(getNodeIndexbyName(graph, datasetsubset.nodename),
                        getNodeIndexbyName(graph, var.nodename)),
                     label = "ds:hasVariable")

  #Add SpatialExtent (Horizontal) node
  var <- unlist(strsplit(recipe$Analysis$Variables$name,
                               ",\\s*"))[[1]]
  refgraph <- get_spatial_extent(data, type, var)
  graph <- my_union_graph(graph, refgraph$graph)
  graph <- add_edges(graph,
                    c(getNodeIndexbyName(graph, datasetsubset.nodename),
                      getNodeIndexbyName(graph, refgraph$parentnodename)),
                    label = "ds:hasHorizontalExtent")

  #TODO:
  #Add SpatialExtent (Vertical) node
  #vextent.nodename <- paste0("VerticalExtent_", type)
  #graph <- add_vertices(graph,
  #                      nv = 1,
  #                      name = vextent.nodename,
  #                      label = "VerticalExtent",
  #                      className = "ds:VerticalExtent")

  #graph <- add_edges(graph,
  #                   c(getNodeIndexbyName(graph, datasetsubset.nodename),
  #                     getNodeIndexbyName(graph, vextent.nodename)),
  #                   label = "ds:hasVerticalExtent")

  # Add members node
  #if (type == "fcst" || type == "hcst") {
  #  browser()
  #  for(i in 1:length(as.numeric(data[[type]]$coords$ensemble))){
  #    mem <- paste0("Member_", type, "_", i)
  #    mem.nodename <- paste0("Realization_", type, "_", i)
  #    mem <- exp_descrip$member[[i]]
  #     graph <- add_vertices(graph,
  #                           nv = 1,
  #                           name = mem.nodename,
  #                           label = ,
  #                           className = "ds:Realization",
  #                           description = "Encode metadata of Realizations",
  #                           attr = list("ds:hasRun" = ))

  #     graph <- add_edges(graph,
  #                        c(getNodeIndexbyName(graph, datasetsubset.nodename),
  #                         getNodeIndexbyName(graph, mem.nodename)),
  #                       label = "ds:hasRealization")
  #  }
  #  }

  #Add TemporalPeriod and Temporal Resolution
  start.time <- list()
  end.time <- list()
  time.step <- list()

  if (var.freq == "monthly_mean" || type == "fcst") {
    for (i in 1:length(data[[type]]$coords$syear)){
      start.time <- append(start.time, format(data[[type]]$attrs$Dates,
                                              format = "%Y-%m-%d %Z")[[i]])
      j <-
        ((length(data[[type]]$coords$time) - 1)
        * length(data[[type]]$coords$syear) + i)
      end.time <- append(end.time, format(data[[type]]$attrs$Dates,
                                          format = "%Y-%m-%d %Z")[[j]])
    }

    freq <- switch(var.freq,
                   "monthly_mean" = "Monthly Mean",
                   "weekly_mean" = "Weekly Mean")

    timeper.nodename <- paste0("TemporalPeriod_", type)
    start.time <- paste(start.time, collapse = " ")
    end.time <- paste(end.time, collapse = " ")
    graph <- add_vertices(graph,
                          nv = 1,
                          name = timeper.nodename,
                          label = "TemporalPeriod",
                          className = "ds:TemporalPeriod",
                          description = "Encode metadata of Temporal Periods",
                          attr = list("prov:startedAtTime" = start.time,
                                        "prov:endedAtTime" = end.time,
                                        "ds:hasTimeFrequency" = freq))

    graph <- add_edges(graph,
                       c(getNodeIndexbyName(graph, datasetsubset.nodename),
                         getNodeIndexbyName(graph, timeper.nodename)),
                       label = "ds:hasValidTemporalExtent")

  } else if (var.freq == "weekly_mean" && type == "hcst" || type == "obs") {
    sdates <- dates2load(recipe, recipe$Run$logger)
    years <- as.numeric(recipe$Analysis$Time$hcst_end) - as.numeric(recipe$Analysis$Time$hcst_start) + 1  
    time_period <- list()
    for (i in 1:years){
      year_week_windows <- sdates$hcst[,,i]
        for (j in 1:recipe$Analysis$Time$sweek_window) {
          week_window <- year_week_windows[j,]
          formatted_dates <- format(as.POSIXct(week_window, format="%Y%m%d"), "%Y-%m-%d 09:00:00")
          week_window_dates <- unlist(paste0("(", paste(formatted_dates, collapse = " - "), ")"))
          time_period[[length(time_period) + 1]] <- week_window_dates
        }

    }

    timeper.nodename <- paste0("TemporalPeriod_", type)
    graph <- add_vertices(graph,
                          nv = 1,
                          name = timeper.nodename,
                          label = "TemporalPeriod",
                          className = "ds:TemporalPeriod",
                          description = "Encode metadata of Temporal Periods",
                          attr = list("prov:value" = paste(unlist(time_period), collapse = " "),
                                      "ds:hasTimeFrequency" = var.freq))

    graph <- add_edges(graph,
                       c(getNodeIndexbyName(graph, datasetsubset.nodename),
                         getNodeIndexbyName(graph, timeper.nodename)),
                       label = "ds:hasValidTemporalExtent")
  }



  return(list("graph" = graph, "parentnodename" = datasetsubset.nodename))
}
