# =============================================================================
# HSCI 841 Qualitative Research Methods and Analysis in Public Health  -  Lesson 6:
#   Analysis Frameworks and Conceptual Models
# Answer key for the in-lesson R activities
# Data file(s): none. Both blocks are self-contained: the heatmap uses the small coded matrix typed
#   into the script, and the process diagram is written in DOT inside the call to grViz().
# Packages: tidyverse, DiagrammeR (optional for the file export: DiagrammeRsvg, rsvg)
#   (install once with install.packages(c("tidyverse", "DiagrammeR", "DiagrammeRsvg", "rsvg")))
# Reproduces every code block in the lesson.
#
# Paths are relative to the course repository root. Set your working directory there
# (Session > Set Working Directory > Choose Directory, or open the course .Rproj) before running.
# =============================================================================

# ==== Section 3.8: R Tools / Code-by-participant heatmap with ggplot2 ====
library(tidyverse)

# Long-format coded data: one row per (participant, code) coded instance
coded <- tribble(
  ~participant, ~code,
  "P01_Maya",     "situational",
  "P01_Maya",     "acute-event",
  "P03_Sarah",    "witness-absence",
  "P03_Sarah",    "structural-attribution",
  "P03_Sarah",    "companioned-loneliness",
  "P03_Sarah",    "maternal-identity-grief",
  "P07_Diana",    "witness-absence",
  "P07_Diana",    "companioned-loneliness",
  "P07_Diana",    "structural-attribution",
  "P10_Daniel",   "existential",
  "P13_Margaret", "structural-isolation",
  "P14_Kenji",    "identity-disruption",
  "P14_Kenji",    "family-rupture",
  "P15_Amira",    "migration-cultural",
  "P15_Amira",    "structural-attribution",
  "P17_Jacob",    "witness-absence",
  "P17_Jacob",    "companioned-loneliness"
)

# Build the wide presence/absence matrix
mat <- coded |>
  mutate(present = 1) |>
  pivot_wider(names_from = code, values_from = present, values_fill = 0) |>
  pivot_longer(-participant, names_to = "code", values_to = "present")

# Plot
ggplot(mat, aes(x = code, y = participant, fill = factor(present))) +
  geom_tile(color = "white", linewidth = 0.5) +
  scale_fill_manual(values = c("0" = "#F3F4F6", "1" = "#0B7B6B"),
                    labels = c("absent", "present"),
                    name = "Code") +
  theme_minimal(base_size = 11) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Codes by participant, loneliness capstone",
       x = NULL, y = NULL)

# Save the figure for the capstone appendix.
# NOTE (answer key): create the output folder first, or ggsave() stops with "no such file or directory".
dir.create("figures", showWarnings = FALSE)
ggsave("figures/wk06_code_heatmap.png", width = 8, height = 4.5, dpi = 150)

# ---- Reading the heatmap ----
cat("Coded instances:", nrow(coded), " participants:", n_distinct(coded$participant),
    " codes:", n_distinct(coded$code), "\n")
witness <- coded |>
  filter(code %in% c("witness-absence", "companioned-loneliness")) |>
  count(participant) |>
  filter(n == 2)
cat("Participants carrying both witness-absence and companioned-loneliness:",
    paste(witness$participant, collapse = ", "), "\n")
# That co-occurrence (P03 Sarah, P07 Diana, P17 Jacob) is the empirical grounding for the
# theoretical memo earlier in the lesson: all three are caregivers who are lonely while
# accompanied. The heatmap is doing analytic work; it makes the pattern visible at a glance.
print(coded |> count(code, sort = TRUE))

# ==== Section 3.8: R Tools / Process diagram with DiagrammeR ====
library(DiagrammeR)

loneliness_cycle <- grViz("
digraph loneliness_cycle {
  graph [layout = dot, rankdir = LR, fontname = 'Open Sans']
  node  [shape = box, style = 'rounded,filled', fillcolor = '#E6F3F0',
         color = '#0B7B6B', fontname = 'Open Sans']
  edge  [color = '#065C50', fontname = 'Open Sans', fontsize = 10]

  trigger    [label = 'Trigger\\n(event or condition)']
  onset      [label = 'Embodied onset\\n(noticed in body)']
  interp     [label = 'Naming & interpretation\\n(attribution)']
  select     [label = 'Response selection']
  enact      [label = 'Response enactment']
  outcome    [label = 'Outcome & learning']

  trigger -> onset
  onset   -> interp
  interp  -> select
  select  -> enact
  enact   -> outcome
  outcome -> interp [label = 'feedback', style = dashed, color = '#CC0033']
  outcome -> select [label = 'feedback', style = dashed, color = '#CC0033']
}
")

# In RStudio the diagram appears in the Viewer pane as soon as you print the object.
loneliness_cycle

# NOTE (answer key): grViz() returns an htmlwidget, which needs a browser to display. To put the
# diagram in a paper, convert it to SVG and then to PNG. Both steps run without a browser.
if (requireNamespace("DiagrammeRsvg", quietly = TRUE) && requireNamespace("rsvg", quietly = TRUE)) {
  dir.create("figures", showWarnings = FALSE)
  svg <- DiagrammeRsvg::export_svg(loneliness_cycle)
  writeLines(svg, "figures/wk06_loneliness_cycle.svg")
  rsvg::rsvg_png(charToRaw(svg), "figures/wk06_loneliness_cycle.png", width = 1400)
  cat("Wrote figures/wk06_loneliness_cycle.svg and .png\n")
} else {
  cat("Install DiagrammeRsvg and rsvg to export the diagram to a file.\n")
}

# The six nodes are the model's claim: loneliness is a cycle, not a state. The two dashed feedback
# edges (outcome -> interpretation, outcome -> response selection) are what make it a cycle, and
# they are the part of the model a reader will challenge, so both must be defensible from coded
# material. Revise a node label and re-render; the diagram is code, not a drawing.
