// Discovery Analysis — report dependency map · DATA
// Nodes, edges, positions, palette, metadata vocab.

// ════════════════════════════════════════════════════════════════════════════
// METADATA VOCABULARY
// ════════════════════════════════════════════════════════════════════════════

const ORIGIN_LABEL = {
  in_app:              "In-app",
  facilitator_prework: "Facilitator pre-work",
  facilitator_workday: "Facilitator workday",
  in_person_workshop:  "In-person / outside app",
  app_assisted_report: "App-assisted report",
  final_export:        "Final export",
};

const STAGE_LABEL = {
  intro:             "Intro meeting",
  pre_work:          "Pre-work",
  between_sessions:  "Between sessions",
  workshop_round_1:  "Workshop · R1",
  workshop_round_2:  "Workshop · R2",
  workshop_round_3:  "Workshop · R3",
  workshop_round_4:  "Workshop · R4",
  workshop_round_5:  "Workshop · R5",
  final:             "Final",
};

const STATUS_LABEL = {
  source_data:           "Source data",
  input_report:          "Input report",
  raw_workshop_artifact: "Raw workshop artifact",
  analytic_report:       "Analytic report",
  final_report:          "Final report",
};

// ════════════════════════════════════════════════════════════════════════════
// NODES
// ════════════════════════════════════════════════════════════════════════════

const NODES = {
  // ─── A · Blueprint self-assessment ────────────────────────────────────
  A: {
    label: "Blueprint self-assessment", sub: "In-app source",
    col: "teal", kind: "input",
    origin: "in_app", stage: "intro", status: "source_data",
    full: "Blueprint Self-Assessment",
    summary: "Participants review the Blueprint in-app, annotate, complete rubric scoring, and produce a scorecard.",
    desc: "Data Point #1 — the baseline current-state view every analytic round orients around. Participants use the app to review the NCEE Blueprint, add annotations / evidence, complete rubric scoring, and produce a scorecard. Construct-level ratings come out of the rubric step (Emerging / On the way / Arrived).",
    whatHappens: "Participant-driven in-app session, typically facilitator-shepherded.",
    keyFields: [
      "Discovery Analysis ID",
      "Focus area (e.g., MCCL, TD Elementary Time, TD HS Time)",
      "Participant annotations + evidence (in-app)",
      "Per construct: rubric score (Emerging / On the way / Arrived)",
      "Scorecard output",
    ],
    generates: "Annotations + rubric scores + scorecard",
  },

  // ─── B · Desk review documents ────────────────────────────────────────
  B: {
    label: "Desk review documents", sub: "Facilitator pre-work",
    col: "teal", kind: "input",
    origin: "facilitator_prework", stage: "pre_work", status: "source_data",
    full: "Desk Review Documents",
    summary: "Facilitators identify or upload 2–3 key pre-work documents such as strategic plans, policies, or memos.",
    desc: "Facilitator-entered. The app may store document metadata, links, notes, and tags for later report generation — it does not interpret the documents on its own. Tags can be surfaced as historical context inside the Iceberg and Futures Triangle activities.",
    whatHappens: "Facilitator-entered: uploads + optional metadata, notes, and tags.",
    keyFields: [
      "Discovery Analysis ID",
      "Per document: title, type, link / storage reference",
      "Per document: short notes / tags",
    ],
    generates: "Tagged document library (facilitator-entered)",
  },

  // ─── C · Interviews / observations ────────────────────────────────────
  C: {
    label: "Interviews / observations", sub: "Facilitator workday",
    col: "teal", kind: "input",
    origin: "facilitator_workday", stage: "between_sessions", status: "source_data",
    full: "Interviews & Observations",
    summary: "Facilitators collect interview and observation notes between intro and in-person workshop.",
    desc: "Facilitator-entered. The app does not run interviews or capture full transcripts. Per interview / observation the facilitator enters a synthesis layer: stakeholder type, role / context, date / mode, 5–10 themes, optional quotes or paraphrases, and optional tags to Blueprint constructs.",
    whatHappens: "Facilitator-entered synthesis layer per interview / observation.",
    keyFields: [
      "Discovery Analysis ID",
      "Per entry: stakeholder type (student, teacher, leader, community)",
      "Per entry: role / context (school, central office, employer)",
      "Per entry: date + mode (interview / focus group / classroom visit)",
      "Per entry: 5–10 themes + optional supporting quotes",
      "Optional tags to Blueprint constructs / focus area",
    ],
    generates: "Stakeholder entries + facilitator-synthesized themes",
  },

  // ─── D · Blueprint SA summary ─────────────────────────────────────────
  D: {
    label: "Blueprint SA summary", sub: "Input report",
    col: "purple", kind: "inputReport",
    origin: "app_assisted_report", stage: "between_sessions", status: "input_report",
    full: "Blueprint SA Summary",
    summary: "App-drafted from the rubric scores. Facilitator-reviewed.",
    desc: "The baseline 'current state' view. App drafts a visual + narrative summary; facilitator reviews, edits, and approves. Low-scoring constructs are commonly chosen as Five Whys problem statements; the focus area frames the Iceberg and Futures Triangle.",
    keyFields: [
      "Discovery Analysis ID",
      "Focus area",
      "Per construct: aggregate rating + facilitator evidence",
    ],
    outputFormat: {
      visual:    "Radar / spider chart or heatmap by construct",
      narrative: "2–3 paragraphs — strengths, growth areas, stakeholder divergence",
      export:    "PDF / HTML section + reusable image(s) for downstream decks",
    },
    generates: "Radar chart + narrative + reusable visuals",
  },

  // ─── E · Desk review summary ──────────────────────────────────────────
  E: {
    label: "Desk review summary", sub: "Input report",
    col: "purple", kind: "inputReport",
    origin: "app_assisted_report", stage: "between_sessions", status: "input_report",
    full: "Desk Review Summary",
    summary: "App-drafted from the tagged document library. Facilitator-reviewed.",
    desc: "Renders the facilitator's tagged documents as a one-row-per-document table and drafts a framing narrative. Facilitator reviews, edits, and approves. Most useful as context for the Iceberg ('events', 'patterns') and Futures Triangle ('weight of history').",
    keyFields: [
      "Discovery Analysis ID",
      "Per document: title, type, key tags",
    ],
    outputFormat: {
      visual:    "Tabular view — one row per document, type + tags",
      narrative: "1–2 paragraphs framing how documents shaped the analysis",
      export:    "Appendix section inside Discovery Analysis report",
    },
    generates: "Tagged document table + framing narrative",
  },

  // ─── F · Stakeholder interview & observation synthesis ────────────────
  F: {
    label: "Interview synthesis", sub: "Input report",
    col: "purple", kind: "inputReport",
    origin: "app_assisted_report", stage: "between_sessions", status: "input_report",
    full: "Stakeholder Interview & Observation Synthesis",
    summary: "App-aggregated synthesis of facilitator-entered themes. Facilitator-reviewed.",
    desc: "The handout participants actually read in Round 1 to surface surprises and confirmations from stakeholder views. App aggregates the per-entry themes; facilitator reviews, edits, and approves. Stakeholder narratives also seed many Iceberg events, patterns, and mental models, and many Five Whys hypotheses.",
    keyFields: [
      "Discovery Analysis ID",
      "Aggregated theme labels across all entries",
      "Optional grouping by stakeholder type",
    ],
    outputFormat: {
      visual:    "One-page bulleted synthesis + optional tag cloud / grouped theme blocks by stakeholder type",
      narrative: "Brief explanation per theme",
      export:    "1–2 page handout for the in-person workshop; also used in final report",
    },
    generates: "One-page stakeholder theme synthesis",
  },

  // ─── W1 · Round 1 — Stakeholder views ─────────────────────────────────
  W1: {
    label: "Round 1", sub: "Stakeholder views",
    col: "amber", kind: "workshopRound",
    origin: "in_person_workshop", stage: "workshop_round_1", status: "raw_workshop_artifact",
    full: "Round 1 — Stakeholder Views",
    summary: "Participants review the Interview Synthesis and identify surprises, confirmations, early hypotheses.",
    desc: "Participants review the Stakeholder Interview & Observation Synthesis during the workshop and identify surprises, confirmations, and early hypotheses. This may happen in person, in Miro, in a shared doc, or through facilitator notes — not necessarily a native app activity unless intentionally supported.",
    whatHappens: "Discussion; outputs are facilitator-captured or imported notes.",
    generates: "Surprises, confirmations, early hypotheses",
  },

  // ─── W2 · Round 2 — Iceberg activity ──────────────────────────────────
  W2: {
    label: "Round 2", sub: "Iceberg activity",
    col: "amber", kind: "workshopRound",
    origin: "in_person_workshop", stage: "workshop_round_2", status: "raw_workshop_artifact",
    full: "Round 2 — Iceberg Activity",
    summary: "Brainstorm tagged to four Iceberg layers.",
    desc: "Workshop activity. Artifacts may be created in Miro, shared docs, paper, or an in-app form. The app treats them as raw workshop artifacts once captured / imported. Input reports D / E / F are typically loaded as reference panels so participants can ground inputs in real evidence.",
    whatHappens: "Per item: short phrase tagged to Events / Patterns / Structures / Mental Models.",
    generates: "Raw layer entries — tagged short phrases or sentences",
  },
  G: {
    label: "Iceberg systems view", sub: "Analytic output · R2",
    col: "coral", kind: "analyticOutput", approved: true,
    origin: "app_assisted_report", stage: "workshop_round_2", status: "analytic_report",
    full: "Iceberg Systems View",
    summary: "App-drafted iceberg + systems narrative. Facilitator-approved.",
    desc: "Once Round 2 artifacts are captured or imported, the app drafts 3–5 themes per band using the SA summary, desk review, and interview synthesis as reference. The facilitator reviews, edits, and approves before the diagram is treated as final.",
    keyFields: [
      "Focus statement",
      "Raw: tagged short phrases per layer",
      "Drafted: 3–5 themes × Events / Patterns / Structures / Mental Models",
    ],
    outputFormat: {
      visual:    "Iceberg diagram, four labeled bands + bullet themes",
      narrative: "1–2 paragraphs — the 'story of the system' across layers",
      export:    "Static graphic + commentary section",
    },
    generates: "Four-layer iceberg + systems narrative",
  },

  // ─── W3 · Round 3 — Futures Triangle ──────────────────────────────────
  W3: {
    label: "Round 3", sub: "Futures Triangle",
    col: "amber", kind: "workshopRound",
    origin: "in_person_workshop", stage: "workshop_round_3", status: "raw_workshop_artifact",
    full: "Round 3 — Futures Triangle Activity",
    summary: "Brainstorm tagged to Push / Weight / Pull.",
    desc: "Workshop activity. Artifacts may be created in Miro, shared docs, paper, or an in-app form. The app treats them as raw workshop artifacts once captured / imported. Push (present forces), Weight (history), Pull (aspirational futures).",
    whatHappens: "Per item: short brainstorm, tagged to one of the three corners.",
    generates: "Raw items tagged to Push / Weight / Pull",
  },
  H: {
    label: "Futures triangle view", sub: "Analytic output · R3",
    col: "coral", kind: "analyticOutput", approved: true,
    origin: "app_assisted_report", stage: "workshop_round_3", status: "analytic_report",
    full: "Futures Triangle View",
    summary: "App-drafted triangle + urgency narrative. Facilitator-approved.",
    desc: "Once Round 3 artifacts are captured or imported, the app drafts 3–5 themes per corner using the SA summary (focus area), desk review (historical policies), and interview synthesis (perceived pressures + aspirations) as reference. Facilitator reviews, edits, and approves.",
    keyFields: [
      "Focus statement (aligned with Iceberg focus)",
      "Raw: items tagged to push / weight / pull",
      "Drafted: 3–5 themes per corner",
    ],
    outputFormat: {
      visual:    "Triangle diagram, three labeled regions + bullet themes",
      narrative: "1–2 paragraphs — urgency, history, aspiration",
      export:    "Single figure + narrative",
    },
    generates: "Triangle diagram + urgency narrative",
  },

  // ─── W4 · Round 4 — Five Whys ─────────────────────────────────────────
  W4: {
    label: "Round 4", sub: "Five Whys",
    col: "amber", kind: "workshopRound",
    origin: "in_person_workshop", stage: "workshop_round_4", status: "raw_workshop_artifact",
    full: "Round 4 — Five Whys Activity",
    summary: "Per-group Why → Answer chains from seeded problem statements.",
    desc: "Workshop activity. Small groups start from a problem statement — typically a low-rated SA construct or an interview hypothesis — and work iterative Why → Answer steps until a structural root cause surfaces. Iceberg + Futures Triangle are displayed as grounding context. Captured / imported as raw artifacts.",
    whatHappens: "Per group: surface problem statement → ordered Why / Answer pairs.",
    generates: "Why → Answer chains, one per small group",
  },
  I: {
    label: "Root-cause sets", sub: "Analytic output · R4",
    col: "coral", kind: "analyticOutput", approved: true,
    origin: "app_assisted_report", stage: "workshop_round_4", status: "analytic_report",
    full: "Root-Cause Problem Sets (Five Whys)",
    summary: "App-drafted clusters of root-cause sets. Facilitator-approved.",
    desc: "Once Round 4 chains are captured or imported, the app drafts 2–3 root-cause sets — each with a clustered statement, 1–2 representative chains, and a theme label (e.g., 'Scheduling constraints', 'Fragmented partnerships'). Facilitator reviews, edits, and approves. Reference: SA summary, interview synthesis, Iceberg structures, Futures Triangle time framing.",
    keyFields: [
      "Raw: per chain — problem statement + ordered Why / Answer pairs",
      "Drafted: 2–3 root-cause sets",
      "Each set: clustered statement + 1–2 representative chains + theme label",
    ],
    outputFormat: {
      visual:    "Per problem set: chain / ladder visual to the root cause",
      narrative: "1–2 sentences per problem set",
      export:    "1–2 page section in Discovery Analysis report",
    },
    generates: "Clustered Why → Answer chains + root-cause labels",
  },

  // ─── W5 · Round 5 — 2×2 ───────────────────────────────────────────────
  W5: {
    label: "Round 5", sub: "2×2 placement",
    col: "amber", kind: "workshopRound",
    origin: "in_person_workshop", stage: "workshop_round_5", status: "raw_workshop_artifact",
    full: "Round 5 — 2×2 Placement Activity",
    summary: "Groups plot candidate topics on urgency × effort.",
    desc: "Workshop activity. Candidate topics come from prior rounds — Iceberg dynamics, Futures urgency, Root-cause sets. Each group independently plots each topic on a urgency × effort matrix. Captured / imported as raw artifacts.",
    whatHappens: "Per group: per topic, urgency + effort placement.",
    generates: "Urgency × effort placements, per group",
  },
  J: {
    label: "Priority 2×2", sub: "Analytic output · R5",
    col: "coral", kind: "analyticOutput", approved: true,
    origin: "app_assisted_report", stage: "workshop_round_5", status: "analytic_report",
    full: "Priority 2×2 (Urgency × Effort)",
    summary: "App-drafted consolidated grid + per-quadrant commentary. Facilitator-approved.",
    desc: "Once Round 5 placements are captured or imported, the app drafts a normalized topic list (collapsing near-duplicates), consensus urgency × effort positions, quadrant classifications, and per-quadrant commentary. Facilitator reviews, edits, and approves. Reference: SA summary, Iceberg, Futures Triangle, Root-cause sets.",
    keyFields: [
      "Raw: per group — topic labels + urgency / effort positions",
      "Drafted: 5–7 normalized topics",
      "Per topic: final urgency, final effort, quadrant classification, optional description",
    ],
    outputFormat: {
      visual:    "Consolidated 2×2 grid — final topic positions, clear labels",
      narrative: "Per quadrant: quick wins / big bets / longer-term / de-prioritized",
      export:    "1–2 page section",
    },
    generates: "Consolidated 2×2 grid + quadrant commentary",
  },

  // ─── K · Final report ─────────────────────────────────────────────────
  K: {
    label: "Discovery report", sub: "Executive summary & recommendations",
    col: "gray", kind: "finalReport",
    origin: "final_export", stage: "final", status: "final_report",
    full: "Discovery Analysis Executive Summary & Recommendations",
    summary: "4–8 page executive brief + ranked recommendations. Bridge into DSTW pathway planning.",
    desc: "App assembles a single document by pulling approved visuals + narratives from all seven upstream reports. Standardized purpose / scope section, summary of findings across the three data points and analytic lenses, and a ranked recommendations section. Each recommendation carries linked constructs / levers, a time horizon (0–12 / 12–24 / 24–36 months), and an optional ranking / sequence. Direct analog of the Benchmarking Lab executive brief; serves as a bridge into DSTW pathway planning.",
    keyFields: [
      "Discovery Analysis ID",
      "Purpose & scope (1–2 paragraphs)",
      "Summary of findings — across the three data points + analytic lenses",
      "Per recommendation: title, description, linked constructs / levers",
      "Per recommendation: time horizon (0–12 / 12–24 / 24–36 months)",
      "Per recommendation: optional ranking / sequence",
    ],
    outputFormat: {
      visual:    "4–8 page PDF — SA chart, Iceberg, Futures Triangle, selected Five Whys, 2×2",
      narrative: "Standardized purpose section + recommendations as narrative + bullets",
      export:    "PDF; visuals reusable in DSTW workshops + Benchmarking Lab-style decks",
    },
    generates: "4–8 page executive brief + ranked recommendations",
  },
};

// ════════════════════════════════════════════════════════════════════════════
// EDGES — two types
//   primary — direct data flow
//   ctx     — contextual reference during synthesis
// ════════════════════════════════════════════════════════════════════════════

const EDGES = [
  // Data → input reports
  ["A","D","primary"], ["B","E","primary"], ["C","F","primary"],

  // Input report → Round 1 (handout to be reviewed)
  ["F","W1","primary"],

  // Workshop round → its analytic output
  ["W2","G","primary"], ["W3","H","primary"],
  ["W4","I","primary"], ["W5","J","primary"],

  // Input reports → analytic outputs (contextual reference)
  ["D","G","ctx"], ["E","G","ctx"], ["F","G","ctx"],
  ["D","H","ctx"], ["E","H","ctx"], ["F","H","ctx"],
  ["D","I","ctx"], ["F","I","ctx"],
  ["D","J","ctx"],

  // Round 1 early hypotheses → later activities (contextual)
  ["W1","G","ctx"], ["W1","I","ctx"],

  // Earlier analytic outputs → later analytic outputs (ctx)
  ["G","I","ctx"], ["H","I","ctx"],
  ["G","J","ctx"], ["H","J","ctx"], ["I","J","ctx"],

  // Final report — all upstream reports compose it
  ["D","K","primary"], ["E","K","primary"], ["F","K","primary"],
  ["G","K","primary"], ["H","K","primary"],
  ["I","K","primary"], ["J","K","primary"],
];

// ════════════════════════════════════════════════════════════════════════════
// LAYOUT
// ════════════════════════════════════════════════════════════════════════════

const POS = {
  // Row 1 · data inputs
  A:  { x:  60, y:  44, w: 190, h: 54 },
  B:  { x: 265, y:  44, w: 190, h: 54 },
  C:  { x: 470, y:  44, w: 190, h: 54 },
  // Row 2 · input reports
  D:  { x:  60, y: 150, w: 190, h: 54 },
  E:  { x: 265, y: 150, w: 190, h: 54 },
  F:  { x: 470, y: 150, w: 190, h: 54 },
  // Row 3 · Round 1 (centered, narrow)
  W1: { x: 250, y: 268, w: 220, h: 44 },
  // Row 4–7 · workshop activity → analytic output pairs
  W2: { x:  70, y: 350, w: 178, h: 54 },
  G:  { x: 290, y: 350, w: 360, h: 54 },
  W3: { x:  70, y: 434, w: 178, h: 54 },
  H:  { x: 290, y: 434, w: 360, h: 54 },
  W4: { x:  70, y: 528, w: 178, h: 54 },
  I:  { x: 290, y: 528, w: 360, h: 54 },
  W5: { x:  70, y: 612, w: 178, h: 54 },
  J:  { x: 290, y: 612, w: 360, h: 54 },
  // Row 8 · final report
  K:  { x: 160, y: 730, w: 400, h: 54 },
};
Object.values(POS).forEach(p => (p.cx = p.x + p.w / 2));

const HORIZ_PAIRS = new Set(["W2-G","W3-H","W4-I","W5-J"]);

const PHASES = [
  { label: "BEFORE WORKSHOP",   y0:  20, y1: 232 },
  { label: "IN-PERSON WORKSHOP",y0: 232, y1: 700 },
  { label: "FINAL EXPORT",      y0: 700, y1: 810 },
];

const SUB_DIVIDERS = [122, 242, 700];

// ════════════════════════════════════════════════════════════════════════════
// COLORS
// ════════════════════════════════════════════════════════════════════════════

const CLT = {
  teal:    { f:"#E1F5EE", s:"#0F6E56", t:"#085041", u:"#1D9E75", h:"#1D9E75" },
  purple:  { f:"#EEEDFE", s:"#534AB7", t:"#3C3489", u:"#534AB7", h:"#534AB7" },
  amber:   { f:"#FAEEDA", s:"#854F0B", t:"#633806", u:"#BA7517", h:"#BA7517" },
  coral:   { f:"#FAECE7", s:"#993C1D", t:"#712B13", u:"#D85A30", h:"#D85A30" },
  gray:    { f:"#E8E5DA", s:"#3F3E3B", t:"#22221F", u:"#5F5E5A", h:"#444441" },
};
const CDK = {
  teal:    { f:"#04342C", s:"#5DCAA5", t:"#9FE1CB", u:"#5DCAA5", h:"#5DCAA5" },
  purple:  { f:"#26215C", s:"#AFA9EC", t:"#CECBF6", u:"#AFA9EC", h:"#AFA9EC" },
  amber:   { f:"#412402", s:"#EF9F27", t:"#FAC775", u:"#EF9F27", h:"#EF9F27" },
  coral:   { f:"#4A1B0C", s:"#F0997B", t:"#F5C4B3", u:"#F0997B", h:"#F0997B" },
  gray:    { f:"#3F3D38", s:"#E8E5DA", t:"#FBFAF6", u:"#D3D1C7", h:"#D3D1C7" },
};

const KIND_LABEL = {
  input:          "Source data",
  inputReport:    "Input report",
  workshopRound:  "Workshop activity",
  analyticOutput: "Analytic report",
  finalReport:    "Final report",
};

const APP_KINDS = new Set(["input","inputReport","analyticOutput","finalReport"]);

const COLOR_LEGEND = [
  { col:"teal",    label:"Data inputs" },
  { col:"purple",  label:"Input reports" },
  { col:"amber",   label:"Workshop activities" },
  { col:"coral",   label:"Analytic outputs" },
  { col:"gray",    label:"Final report" },
];

// Origin → dot color (light + dark) for the origin legend.
// Encodes "where does this happen / how does it get into the app."
const ORIGIN_LEGEND = [
  { v: "in_app",              label: "In-app",                  light:"#1D9E75", dark:"#5DCAA5" },
  { v: "facilitator_prework", label: "Facilitator pre-work",    light:"#534AB7", dark:"#AFA9EC" },
  { v: "facilitator_workday", label: "Facilitator workday",     light:"#534AB7", dark:"#AFA9EC" },
  { v: "in_person_workshop",  label: "In-person / outside app", light:"#BA7517", dark:"#EF9F27" },
  { v: "app_assisted_report", label: "App-assisted report",     light:"#D85A30", dark:"#F0997B" },
  { v: "final_export",        label: "Final export",            light:"#444441", dark:"#D3D1C7" },
];

// ── Pre-computed graph helpers ────────────────────────────────────────

const PARENTS = {};
const CHILDREN = {};
const EDGE_TYPE = {};
EDGES.forEach(([s, t, type]) => {
  (PARENTS[t]  = PARENTS[t]  || []).push(s);
  (CHILDREN[s] = CHILDREN[s] || []).push(t);
  EDGE_TYPE[`${s}-${t}`] = type;
});

function traverse(id, direction) {
  const map = direction === "down" ? CHILDREN : PARENTS;
  const seen = new Set(), q = [id];
  while (q.length) {
    const cur = q.shift();
    (map[cur] || []).forEach(n => {
      if (!seen.has(n)) { seen.add(n); q.push(n); }
    });
  }
  return seen;
}

Object.assign(window, {
  NODES, EDGES, POS, HORIZ_PAIRS, PHASES, SUB_DIVIDERS,
  CLT, CDK, KIND_LABEL, APP_KINDS,
  ORIGIN_LABEL, STAGE_LABEL, STATUS_LABEL,
  COLOR_LEGEND, ORIGIN_LEGEND,
  PARENTS, CHILDREN, EDGE_TYPE, traverse,
});
