/* Demo data — TBI cohort, behavior + qPCR + ELISA, mouse */

const DEMO_STUDY = {
  id: "STD-2026-014",
  title: "TBI treatment cohort: behavior plus inflammatory markers",
  shortTitle: "TBI inflammatory markers cohort",
  species: "Mus musculus (C57BL/6J)",
  cohortSize: 36,
  groups: ["Sham", "TBI", "TBI + treatment"],
  assayTypes: ["Open field (behavior)", "qPCR", "ELISA"],
  status: "Analysis-ready review",
  readinessScore: 83,
  pi: "He Lab · Significance Lab",
  startDate: "2026-04-12",
  lastTouched: "2026-05-24 09:42",
};

const DEMO_SUBJECTS = [
  // Sham n=12
  ...range(1, 13).map(i => sub(`M${pad(i)}`, "Sham", i % 2 ? "F" : "M", "WT")),
  // TBI n=12
  ...range(13, 25).map(i => sub(`M${pad(i)}`, "TBI", i % 2 ? "F" : "M", "WT")),
  // TBI + treatment n=12
  ...range(25, 37).map(i => sub(`M${pad(i)}`, "TBI + treatment", i % 2 ? "F" : "M", "WT")),
];

// Mark a couple of subjects with missing fields per spec ("1 subject missing sex")
DEMO_SUBJECTS[18].sex = undefined; // M19
function sub(id, group, sex, genotype) {
  return { subjectId: id, group, sex, genotype };
}
function range(a, b) { const out = []; for (let i = a; i < b; i++) out.push(i); return out; }
function pad(n) { return String(n).padStart(2, "0"); }

// Samples — 3 timepoints (baseline, 24h, 7d) for each subject × assay
const TIMEPOINTS = ["baseline", "24h", "7d"];
const DEMO_SAMPLES = [];
DEMO_SUBJECTS.forEach((s, idx) => {
  TIMEPOINTS.forEach((tp, ti) => {
    DEMO_SAMPLES.push({
      sampleId: `S-${s.subjectId}-${tp.toUpperCase().replace(/[^A-Z0-9]/g, "")}`,
      subjectId: s.subjectId,
      assayType: "qPCR",
      timepoint: tp,
      sourceFile: "qpcr_run_0524.rdml",
    });
    DEMO_SAMPLES.push({
      sampleId: `E-${s.subjectId}-${tp.toUpperCase().replace(/[^A-Z0-9]/g, "")}`,
      subjectId: s.subjectId,
      assayType: "ELISA",
      timepoint: tp,
      sourceFile: "il6_tnfa_elisa_plate.csv",
    });
  });
  DEMO_SAMPLES.push({
    sampleId: `B-${s.subjectId}`,
    subjectId: s.subjectId,
    assayType: "behavior",
    timepoint: "24h",
    sourceFile: "open_field_summary.csv",
  });
});

// Knock out timepoint on two qPCR samples per spec ("2 samples missing timepoint")
DEMO_SAMPLES[3].timepoint = undefined;
DEMO_SAMPLES[11].timepoint = undefined;

const DEMO_FILES = [
  {
    name: "qpcr_run_0524.rdml",
    kind: "RDML · qPCR",
    source: "bench",
    rowsParsed: 384,
    mappedSamples: 108,
    warnings: 2,
    linkedSubjects: 36,
    uploaded: "2026-05-22",
    detail: "Plate A · 96-well · IL6, TNFa, GAPDH (ref) · 4 plates",
  },
  {
    name: "il6_tnfa_elisa_plate.csv",
    kind: "CSV · ELISA",
    source: "bench",
    rowsParsed: 192,
    mappedSamples: 108,
    warnings: 0,
    linkedSubjects: 36,
    uploaded: "2026-05-22",
    detail: "Bio-Plex · IL-6 (pg/mL) + TNFα (pg/mL) · standard curve attached",
  },
  {
    name: "sample_map.csv",
    kind: "CSV · sample map",
    source: "bench",
    rowsParsed: 252,
    mappedSamples: 252,
    warnings: 1,
    linkedSubjects: 36,
    uploaded: "2026-05-22",
    detail: "Subject ↔ sample ↔ assay map · 1 row missing timepoint",
  },
  {
    name: "open_field_summary.csv",
    kind: "CSV · behavior (ConductVision)",
    source: "vision",
    rowsParsed: 36,
    mappedSamples: 36,
    warnings: 1,
    linkedSubjects: 36,
    uploaded: "2026-05-23",
    detail: "10-min open field · distance, center time, freezing · native ConductVision attach",
  },
];

const DEMO_READINESS = [
  { severity: "warning",  label: "2 samples missing timepoint",
    detail: "S-M02-BASELINE, S-M04-24H · qPCR. Resolve by filling sample_map.csv or marking as excluded.",
    file: "sample_map.csv" },
  { severity: "warning",  label: "1 subject missing sex",
    detail: "M19 (TBI group). Add sex to subject record before group summary.",
    file: "subjects (manual)" },
  { severity: "complete", label: "All sample IDs match qPCR wells",
    detail: "108/108 sample IDs in qpcr_run_0524.rdml resolve to a known sample." },
  { severity: "complete", label: "ELISA units detected (pg/mL)",
    detail: "il6_tnfa_elisa_plate.csv reports IL-6 and TNFα in pg/mL with standard curve attached." },
  { severity: "complete", label: "All 36 subjects assigned to a group",
    detail: "Sham (12) · TBI (12) · TBI + treatment (12)." },
  { severity: "complete", label: "qPCR reference gene present",
    detail: "GAPDH detected as reference on all 4 plates · Ct CV < 0.5 across replicates." },
  { severity: "complete", label: "ConductVision behavior file attached natively",
    detail: "open_field_summary.csv arrived via the native ConductVision attach. Linked on subject ID with no manual mapping." },
  { severity: "blocking", label: "0 blocking issues",
    detail: "Study is analysis-ready. Resolve the 2 remaining warnings to lift the readiness score above 90." },
];

// Pre-computed endpoint table — one row per subject × timepoint where data exists
function r(min, max, dp = 2) { return +(Math.random() * (max - min) + min).toFixed(dp); }
function seed(s) { let x = s; return () => { x = (x * 9301 + 49297) % 233280; return x / 233280; }; }
const rng = seed(42);
function rr(min, max, dp = 2) { return +((rng() * (max - min) + min)).toFixed(dp); }

const DEMO_ENDPOINTS = [];
DEMO_SUBJECTS.forEach(s => {
  // Group-conditioned distributions
  const isTBI = s.group === "TBI";
  const isTx  = s.group === "TBI + treatment";
  const isSham = s.group === "Sham";

  TIMEPOINTS.forEach(tp => {
    const row = {
      subjectId: s.subjectId,
      group: s.group,
      timepoint: tp,
    };
    if (tp === "24h") {
      // Behavior: TBI reduces distance, treatment partially rescues
      const base = isSham ? rr(2800, 3400) : isTBI ? rr(1500, 2100) : rr(2200, 2800);
      row.behaviorDistanceCm = +base.toFixed(0);
    }
    // qPCR fold change IL-6 vs sham baseline
    const fcBase = isSham ? rr(0.85, 1.15) : isTBI ? rr(3.4, 6.8) : rr(1.6, 3.1);
    const fcMod  = tp === "baseline" ? rr(0.85, 1.15) : tp === "24h" ? 1 : rr(0.7, 1.1);
    row.qpcrFoldChange = +(fcBase * fcMod).toFixed(2);

    // ELISA IL-6 pg/mL
    const elBase = isSham ? rr(8, 18) : isTBI ? rr(120, 260) : rr(45, 95);
    const elMod  = tp === "baseline" ? rr(0.4, 0.7) : tp === "24h" ? 1 : rr(0.5, 0.85);
    row.elisaConcentrationPgMl = +(elBase * elMod).toFixed(1);

    // QC flag
    if (s.subjectId === "M19" && tp === "baseline") row.qcFlag = "missing-sex";
    else if (s.subjectId === "M02" && tp === "baseline") row.qcFlag = "missing-tp";
    else if (s.subjectId === "M04" && tp === "24h") row.qcFlag = "missing-tp";
    else row.qcFlag = "ok";

    DEMO_ENDPOINTS.push(row);
  });
});

const DEMO_METHODS_SHORT = `Subjects (n=36 C57BL/6J mice) were assigned to Sham, TBI, or TBI + treatment groups (n=12 each). At baseline, 24h, and 7d post-injury, peripheral blood and trunk tissue were collected. IL-6 and TNFα were quantified by ELISA (Bio-Plex, pg/mL) against a standard curve. IL-6 mRNA was quantified by qPCR (RDML run 0524) normalized to GAPDH and reported as fold change vs. sham baseline. At 24h, locomotor activity was measured in a 10-min open field assay (ConductVision native attach). Records were joined on subject_id × timepoint in ConductBench v3.2 on 2026-05-24. Two samples missing timepoint and one subject missing sex are flagged in the joined record (2 warnings, 0 blocking).`;

const DEMO_METHODS_LONG = `Subjects. n=36 male and female C57BL/6J mice (8–10 weeks, sex-balanced) were assigned to three groups by stratified randomization: Sham (n=12), TBI (n=12), and TBI + treatment (n=12). One subject (M19, TBI group) is missing a recorded sex in the subject roster (flagged as warning).

Procedure. TBI was induced by controlled cortical impact (Leica Impact One, 5 mm tip, 1.5 mm depth, 4 m/s, 200 ms dwell). Sham animals received craniotomy without impact. Treatment animals received minocycline (45 mg/kg IP) at 30 min and 24 h post-injury. Behavior. At 24 h post-injury, animals were tested in a 10-min open field (40 × 40 cm arena). Distance traveled (cm), center time (s), and freezing episodes were attached from ConductVision (native attach on subject ID). Molecular. Peripheral blood (~80 µL retro-orbital) and ipsilateral cortex tissue were collected at baseline (pre-injury), 24 h, and 7 d. ELISA. Plasma IL-6 and TNFα were quantified using a Bio-Plex multiplex panel against a 7-point standard curve (pg/mL; CV < 12% across duplicates). qPCR. Total RNA was extracted (Qiagen RNeasy), reverse-transcribed (1 µg input), and amplified for Il6 and Tnf with Gapdh as reference. RDML output (run 0524, 4 × 96-well plates, 384 wells) was parsed and joined on sample_id. Fold change is reported as 2^(−ΔΔCt) vs. sham baseline.

Joining. Records were joined in ConductBench v3.2 on subject_id × timepoint. Sample map: sample_map.csv (252 rows). 108/108 qPCR sample IDs and 108/108 ELISA sample IDs resolve cleanly. Missingness: two qPCR samples (S-M02-BASELINE, S-M04-24H) are missing a timepoint label and were retained but flagged in the joined table (qcFlag=missing-tp). Statistics. Group differences were tested by two-way ANOVA (group × timepoint) with Tukey post-hoc; data presented as mean ± SEM. Behavior was compared by one-way ANOVA. α = 0.05.

Provenance. Files used: qpcr_run_0524.rdml (SHA-256 7a2c…3e91), il6_tnfa_elisa_plate.csv (SHA-256 0bb4…91ad), sample_map.csv (SHA-256 1cc5…2f10), open_field_summary.csv (SHA-256 2dd8…7bcb). Software: ConductBench v3.2. Export timestamp: 2026-05-24T09:42:18Z. Methods text and joined endpoint table are reproducible from the listed file hashes.`;

Object.assign(window, {
  DEMO_STUDY, DEMO_SUBJECTS, DEMO_SAMPLES, DEMO_FILES,
  DEMO_READINESS, DEMO_ENDPOINTS, DEMO_METHODS_SHORT, DEMO_METHODS_LONG,
  TIMEPOINTS,
});
