---
output: 
  # distill::distill_article:
  #   theme: flatly
  #   self_contained: true
  #   toc: true
  #   toc_depth: 3
  #   toc_float: true
  #   css: "report_styles.css"
  html_document:
    theme: flatly
    css: project-snapshot_styles.css
    self_contained: true
    toc: true
    toc_depth: 3
    toc_float: true
---


```{r setup, include=FALSE}
knitr::opts_chunk$set(
  eval = TRUE,
  echo = FALSE,
  # collapse = TRUE,
  warning = FALSE,
  message = FALSE
)

# This document must be built under pipeline directory
```

```{r initial_setup, include=FALSE}
ravecore <- asNamespace("ravecore")
path_rel <- ravecore$path_rel
new_rave_subject <- ravecore$new_rave_subject
get_projects <- ravecore$get_projects
as_rave_project <- ravecore$as_rave_project

if (system.file(package = "DT") == "") {
  stop("Please run `install.packages('DT')` before generating this report.")
}
DT <- asNamespace("DT")
datatable <- DT$datatable

working_path <- normalizePath(".")
project_info <- readRDS(file.path(working_path, "snapshot.rds"))
project_name <- project_info$project_name
```

---
title: "`r sprintf('%s (%d subjects)', project_info$project_name, length(project_info$subject_codes))`"
---

<small><i>
  An automated report generated by 
  <a target="_blank" href="https://rave.wiki">
    RAVE
  </a>
  at `r strftime(project_info$timestamp, '%H:%M:%S, %b %d, %Y')` 
  <span id="description-time-ago"><span>
</i></small>

<div id="page_info" class="hidden" style="display:none !important;" data='{"project_name":"`r project_info$project_name`"}'>

</div>

## Group Viewers

```{r, show_viewer, echo=FALSE, results='asis'}
htmltools::tags$ul(
  lapply(project_info$template_subjects, function(template_subject) {
    viewer_path <- sprintf("group_viewer-%s.html", template_subject)
    htmltools::tags$li(
      htmltools::HTML(sprintf(
        '<a data-href="%s" data-meta=\'{"project_name":"%s"}\'>Group viewer (template: %s)</a>',
        viewer_path, project_name, template_subject
      ))
    )
  })
)
```

## Electrode Summary

```{r electrode_summary_table}
#| layout: 'l-screen-insert-right'
subject_codes <- project_info$subject_codes
electrode_tables <- lapply(subject_codes, function(subject_code) {
  rds <- file.path(working_path, subject_code, "snapshot.rds")
  if (!file.exists(rds)) { return(NULL) }
  subject_info <- readRDS(rds)
  tbl <- subject_info$meta$electrode_table
  if (!is.data.frame(tbl) || !nrow(tbl)) { return(NULL) }
  if (!length(tbl$FSLabel)) {
    tbl$FSLabel <- "Unknown"
  }
  data.frame(
    Subject = subject_code,
    FSLabel = tbl$FSLabel
  )
})
electrode_tables <- data.table::rbindlist(electrode_tables)
if (nrow(electrode_tables) > 0) {
  summary_table <- stats::reshape(
    stats::aggregate(
      list(count = electrode_tables$FSLabel),
      by = list(FSLabel = electrode_tables$FSLabel,
                Subject = electrode_tables$Subject),
      FUN = length
    ),
    timevar   = "Subject",
    idvar     = "FSLabel",
    direction = "wide"
  )
  
  names(summary_table) <- sub("^count\\.", "", names(summary_table))
  summary_table[is.na(summary_table)] <- 0
  # summary_table <- reshape2::dcast(electrode_tables,
  #                                  FSLabel ~ Subject,
  #                                  fun.aggregate = length,
  #                                  fill = 0, value.var = "FSLabel")
  datatable(
    summary_table,
    class = "compact stripe nowrap",
    rownames = FALSE,
    fillContainer = FALSE,
    options = list(
      scrollX = TRUE,        # allow horizontal scrolling
      scrollY = FALSE,
      lengthMenu = list(c(10, 25, 50, 100, -1), c("10", "25", "50", "100", "All")), 
      paging = TRUE
    )
  )
} else {
  message("No valid electrode table within this project")
}
```

## Subject Summary

```{r subject_summary, echo=FALSE}
#| layout: 'l-screen-insert-right'
subject_summary <- lapply(subject_codes, function(subject_code) {
  subject_path <- file.path(working_path, subject_code)
  rds <- file.path(subject_path, "snapshot.rds")
  if (!file.exists(rds)) { return(NULL) }
  subject_info <- readRDS(rds)
  
  row <- list()
  
  if (file.exists(file.path(subject_path, "electrode_table.html"))) {
    electrode_table_html <- htmltools::HTML(sprintf(
      '<a data-href="%s/electrode_table.html" data-meta=\'{"project_name":"%s"}\'>n=%d</a>',
      subject_code, project_name, subject_info$meta$electrodes
    ))
  } else {
    electrode_table_html <- "(missing table)"
  }
  
  # viewer
  if (file.exists(file.path(subject_path, "viewer.html"))) {
    viewer_html <- htmltools::HTML(sprintf(
      '<a data-href="%s/viewer.html" data-meta=\'{"project_name":"%s"}\'>viewer</a>',
      subject_code, project_name
    ))
  } else {
    viewer_html <- "(missing viewer)"
  }
  row$Electrodes <- htmltools::span(
    electrode_table_html, " | ", viewer_html
  )
  
  
  # Epochs
  epoch_tables <- lapply(names(subject_info$meta$epochs), function(epoch_name) {
    nr <- subject_info$meta$epochs[[epoch_name]]
    epoch_fname <- sprintf("epoch-%s.html", epoch_name)
    epoch_path <- file.path(subject_path, epoch_fname)
    if (!file.exists(epoch_path)) { return() }
    htmltools::tags$li(
      htmltools::HTML(sprintf(
        '<a data-href="%s/epoch-%s.html" data-meta=\'{"project_name":"%s"}\'><span style="font-weight:600">%s</span>: %d</a>',
        subject_code, epoch_name, project_name, epoch_name, nr
      ))
    )
  })
  row$Epoch <- htmltools::tags$ul(epoch_tables)
  
  # References
  reference_tables <- lapply(
    X = names(subject_info$meta$references),
    FUN = function(reference_name) {
      nr <- subject_info$meta$references[[reference_name]]
      reference_fname <- sprintf("reference-%s.html", reference_name)
      reference_path <- file.path(subject_path, reference_fname)
      if (!file.exists(reference_path)) {
        return()
      }
      htmltools::tags$li(
        htmltools::HTML(sprintf(
          '<a data-href="%s/reference-%s.html" data-meta=\'{"project_name":"%s"}\'>%s</a>',
          subject_code, reference_name, project_name, reference_name
        ))
      )
    }
  )
  row$Reference <- htmltools::tags$ul(reference_tables)
  
  data.frame(
    Subject = subject_code,
    Electrode = paste(format(row$Electrodes), collapse = "\n"),
    ImportedBlock = paste(subject_info$blocks, collapse = ", "),
    Epoch = paste(format(row$Epoch), collapse = "\n"),
    Reference = paste(format(row$Reference), collapse = "\n")
  )
  # list(
  #   brain_viewer = brain_viewer,
  #   electrode_table = electrode_table,
  #   epoch_tables = epoch_tables,
  #   reference_tables = reference_tables
  # )
})

subject_summary <- do.call("rbind", subject_summary)
datatable(
  subject_summary,
  class = "compact stripe nowrap",
  rownames = FALSE,
  escape = FALSE,
  fillContainer = FALSE,
  options = list(
    scrollX = TRUE,        # allow horizontal scrolling
    scrollY = FALSE,
    pageLength = -1,                     # show all rows by default
    lengthMenu = list(c(20, 50, 100, -1), c("20", "50", "100", "All")), 
    paging = TRUE
  )
)
```

## Module Reports

```{r generate_report_table, echo = FALSE}
project_name <- project_info$project_name
report_list <- lapply(subject_codes, function(subject_code) {
  subject <- new_rave_subject(project_name = project_name,
                              subject_code = subject_code,
                              strict = FALSE)
  report_relpath <- path_rel(subject$report_path, working_path)
  report_dnames <- list.files(
    subject$report_path,
    pattern = "^report-.*_datetime-[0-9]{6}T[0-9]{6}_.*$",
    recursive = FALSE,
    include.dirs = TRUE,
    all.files = FALSE,
    full.names = FALSE,
    ignore.case = FALSE,
    no.. = TRUE
  )
  match_info <- regexec("^report-(.*)_datetime-([0-9]{6}T[0-9]{6})_(.*)$", report_dnames)
  lapply(regmatches(report_dnames, match_info), function(m) {
    report_dname <- m[[1]]
    report_path <- file.path(subject$report_path, report_dname, "report.html")
    if (!file.exists(report_path)) { return() }
    url_params <- list(
      type = "report",
      project_name = project_name,
      subject_code = subject_code,
      report_filename = m[[1]]
    )
    
    list(
      Subject = subject_code,
      Time = as.POSIXct(strptime(m[[3]], "%y%m%dT%H%M%S")),
      ModuleID = m[[4]],
      ReportID = m[[2]],
      Link = sprintf(
        '<a data-href="%s/%s/report.html" data-meta=\'%s\'>[link]</a>',
        report_relpath, m[[1]], enc2utf8(jsonlite::toJSON(url_params, auto_unbox = TRUE))
      )
    )
  })
})
report_list <- unlist(report_list, recursive = FALSE, use.names = FALSE)
report_table <- data.table::rbindlist(report_list)
if (nrow(report_table) > 0) {
  report_table <- report_table[order(report_table$Time, na.last = TRUE, decreasing = TRUE), ]
  
  datatable(
    report_table,
    class = "compact stripe nowrap",
    rownames = FALSE,
    escape = FALSE,
    fillContainer = FALSE,
    options = list(
      scrollX = TRUE,        # allow horizontal scrolling
      scrollY = FALSE,
      lengthMenu = list(c(20, 50, 100, -1), c("20", "50", "100", "All")), 
      paging = TRUE
    )
  )
} else {
  message("No report available")
}

```

## Data Check Results


```{r generate_validation_table, echo=FALSE}
#| layout: 'l-screen-insert-right'
validator_summary <- lapply(subject_codes, function(subject_code) {
  subject_path <- file.path(working_path, subject_code)
  rds <- file.path(subject_path, "snapshot.rds")
  if (!file.exists(rds)) { return(NULL) }
  subject_info <- readRDS(rds)
  
  validation <- as.list(subject_info$validation, recursive = TRUE)
  validation <- unlist(validation, use.names = TRUE, recursive = FALSE)

  results <- lapply(names(validation), function(nm) {
    v <- validation[[nm]]
    if (isFALSE(v$valid)) {
      return(
        list(
          Subject = subject_code,
          Key = nm,
          Description = v$description,
          Validation = sprintf("[%s] %s", v$severity, paste(v$message, collapse = ""))
        )
      )
    } else {
      return(NULL)
    }
  })
  results <- results[!vapply(results, is.null, FUN.VALUE = FALSE)]
  if (length(results)) {
    validation_table <- data.table::rbindlist(results)
  } else {
    validation_table <- NULL
  }
  validation_table
})
validator_summary <- data.table::rbindlist(validator_summary)

datatable(
  validator_summary,
  class = "compact stripe nowrap",
  rownames = FALSE,
  fillContainer = FALSE,
  options = list(
    scrollX = TRUE,        # allow horizontal scrolling
    scrollY = FALSE,
    lengthMenu = list(c(10, 25, 50, 100, -1), c("10", "25", "50", "100", "All")), 
    paging = TRUE
  )
)
```

## Quick Switch to Other Projects

```{r generate_project_links, echo=FALSE}
all_projects <- get_projects()
all_projects <- all_projects[all_projects != project_name]
htmltools::tags$ul(
  lapply(all_projects, function(project_name2) {
    tryCatch({
      project2 <- as_rave_project(project_name2, strict = FALSE)
      report2_path <- file.path(project2$group_path("project_overview"), "snapshot", "project-report.html")
      htmltools::tags$li(
        htmltools::HTML(sprintf(
          '<a data-href="%s" data-meta=\'{"project_name":"%s","alt_path":"project-report.html"}\'>%s</a>',
          path_rel(report2_path, working_path), project_name2, project_name2
        ))
      )
    }, error = function(e) {
      NULL
    })
  })
)
```

<script>
document.addEventListener("DOMContentLoaded", function() {
  const hrefs = document.querySelectorAll("a[data-href]");
  const usingSrcdoc = window.location.protocol.startsWith("about");
  hrefs.forEach(href => {
    let link = href.getAttribute("data-href");
    if( usingSrcdoc ) {
      const urlParams = new URLSearchParams();
      try {
        const meta = JSON.parse(href.getAttribute("data-meta"));
        urlParams.set("project_name", meta['project_name']);
        urlParams.set("module", "standalone_report");
        urlParams.set("type", "widget");
        if( meta['type'] === 'report' ) {
          // This is a report
          urlParams.set("subject_code", meta['subject_code']);
          urlParams.set("report_filename", meta['report_filename']);
        } else {
          // snapshot
          urlParams.set("snapshot", 1);
          if(typeof meta["alt_path"] === "string") {
            // relative to root
            urlParams.set("path", meta["alt_path"]);
          } else {
            urlParams.set("path", link);
          }
        }
        link = `?${urlParams.toString()}`;
      } catch (error) {}
    }
    href.href = link;
    href.target = "_blank";
  });
  const diffMs = Date.now() - new Date("`r format(project_info$timestamp, '%Y-%m-%d %H:%M:%S')`");
  // helper to format as "1yr 3hrs ago"
  function formatAgo(ms) {
    const sec = Math.floor(ms / 1000);
    const min = Math.floor(sec / 60);
    const hr  = Math.floor(min / 60);
    const day = Math.floor(hr / 24);
    const yr  = Math.floor(day / 365);
    let parts = [];
    if (yr) parts.push(yr + "yr");
    const remDay = day % 365;
    const remHr  = hr % 24;
    if (!yr && remDay) parts.push(remDay + "d");
    if (!yr && !remDay && remHr) parts.push(remHr + "hr");
    if (!yr && !remDay && !remHr) parts.push(Math.max(min % 60,1) + "min");
    return parts.join(" ") + " ago";
  }
  const displayAgo = document.getElementById("description-time-ago");
  displayAgo.textContent = `(${formatAgo(diffMs)})`
});
</script>
