// Documentation Drafts — PES Builder, generated note sections, full note output.
const { useState: useStateDoc, useMemo: useMemoDoc, useEffect: useEffectDoc, useRef: useRefDoc } = React;

const RD = window.RD;
const {
  PROBLEMS, DX_INTERVENTIONS, COMORBIDITY_INTERVENTIONS,
  FOOD_SECURITY_INTERVENTIONS, DX_MONITORING, PES_HELP,
  ENERGY_METHODS, ACTIVITY, FOOD_SECURITY, FLUID_METHODS,
  proteinDefaultsFor, devineIBW, adjustedBodyWeight, toCm, toKg,
  CALORIC_ADJUSTMENTS, seedPES, computeBMI, bmiStatus,
} = RD;

const fmtD = n => Number.isFinite(n) ? Math.round(n).toLocaleString() : "—";
const fmtD1 = n => Number.isFinite(n) ? n.toFixed(1) : "—";
const fmtD2 = n => Number.isFinite(n) ? n.toFixed(2) : "—";

const fmtD3 = n => Number.isFinite(n) ? n.toFixed(3) : "—";

// Chart-language position of the default within the range (no UI phrasing).
function proteinPositionText(d) {
  const dx = d.dxDefaults;
  if (!dx || !Number.isFinite(dx.low) || !Number.isFinite(dx.high)) return "";
  const rangeTxt = `${fmtD2(dx.low)}–${fmtD2(dx.high)} range`;
  const actTxt = d.activityRow ? `, ${d.activityRow.label.toLowerCase()}` : "";
  if (d.proteinBasis == null) return `; ${rangeTxt}${actTxt}`;
  if (Math.abs(dx.high - dx.low) < 1e-9) return `; ${rangeTxt}${actTxt}`;
  const t = (d.proteinBasis - dx.low) / (dx.high - dx.low);
  const pos = t <= 0.001 ? "low end of" : t >= 0.999 ? "high end of" : Math.abs(t - 0.5) < 0.001 ? "midpoint of" : "within";
  return `; ${pos} ${rangeTxt}${actTxt}`;
}

// ---------------------------------------------------------------------------
// Computed values used by both the generated sections and the full-note output
// ---------------------------------------------------------------------------
function deriveNote(state, calc) {
  const ageNum = parseFloat(state.age);
  const weightKg = state.weight ? toKg(parseFloat(state.weight), state.weightUnit) : null;
  const heightCm = state.height ? toCm(parseFloat(state.height), state.heightUnit) : null;
  const sex = state.sex;
  const dxId = state.diagnosis?.id;
  const ready = Number.isFinite(ageNum) && Number.isFinite(weightKg) && Number.isFinite(heightCm);

  // Energy
  const method = ENERGY_METHODS.find(m => m.id === calc.energyMethod) || ENERGY_METHODS[0];
  const computedBMR = ready ? method.fn(weightKg, heightCm, ageNum, sex) : null;
  const bmr = calc.bmrOverride != null ? calc.bmrOverride : computedBMR;
  const activityRow = ACTIVITY.find(a => a.id === state.activity);
  const computedActivity = activityRow?.mult ?? null;
  const activityMult = calc.activityMultOverride != null ? calc.activityMultOverride : computedActivity;
  const stress = calc.stressFactor;
  const computedTDEE = (Number.isFinite(bmr) && Number.isFinite(activityMult)) ? bmr * activityMult * stress : null;
  const tdee = calc.tdeeOverride != null ? calc.tdeeOverride : computedTDEE;
  const caloricAdj = CALORIC_ADJUSTMENTS.find(c => c.id === calc.caloricAdjustment) || CALORIC_ADJUSTMENTS[2];
  const energyNeeds = Number.isFinite(tdee) ? RD.applyModifiers("energy", tdee + caloricAdj.value, state) : null;

  // Protein — v1d S4/S5 shared resolver
  const dxDefaults = ready && dxId ? proteinDefaultsFor(dxId, ageNum, state.activity) : null;
  const wb = RD.resolveProteinWeight({ weightKg, heightCm, sex }, calc, dxDefaults, state);
  const { proteinWeight, ibw, abw } = wb;
  const proteinBasisLabel = wb.basisLabel;
  const range = dxDefaults ? RD.applyModifiers("protein", { low: dxDefaults.low, high: dxDefaults.high, point: dxDefaults.point }, state) : null;
  const computedBasis = range ? (Number.isFinite(range.point) ? range.point : (range.low + range.high) / 2) : null;
  const proteinBasis = calc.proteinBasisOverride != null ? calc.proteinBasisOverride : computedBasis;
  const proteinG = (Number.isFinite(proteinBasis) && Number.isFinite(proteinWeight)) ? proteinBasis * proteinWeight : null;

  // Fluids
  const fluidMethod = FLUID_METHODS.find(f => f.id === calc.fluidMethod) || FLUID_METHODS[0];
  let computedFluid = null;
  if (calc.fluidMethod === "perKcal" && Number.isFinite(energyNeeds)) {
    computedFluid = energyNeeds * 1;
  } else if (calc.fluidMethod === "perKg" && Number.isFinite(weightKg)) {
    computedFluid = weightKg * 32.5;
  }
  const fluid = calc.fluidValueOverride != null ? calc.fluidValueOverride : computedFluid;

  // BMI
  const bmi = computeBMI(state);
  const bmiSt = bmiStatus(bmi, ageNum);

  return {
    ready, ageNum, weightKg, heightCm, sex, dxId,
    method, bmr, activityMult, activityRow, stress, tdee, caloricAdj, energyNeeds,
    dxDefaults, proteinWeight, proteinBasisLabel, ibw, abw, proteinBasis, proteinG,
    fluidMethod, fluid,
    bmi, bmiSt,
  };
}

// ---------------------------------------------------------------------------
// Generated interventions / monitoring (string lists)
// ---------------------------------------------------------------------------
function generatedInterventions(state) {
  const dxId = state.diagnosis?.id || "other";
  const out = [];
  out.push(...(DX_INTERVENTIONS[dxId] || DX_INTERVENTIONS.other));
  for (const c of state.comorbidities || []) {
    if (COMORBIDITY_INTERVENTIONS[c]) out.push(...COMORBIDITY_INTERVENTIONS[c]);
  }
  if (state.foodSecurity && FOOD_SECURITY_INTERVENTIONS[state.foodSecurity]) {
    out.push(...FOOD_SECURITY_INTERVENTIONS[state.foodSecurity]);
  }
  // dedupe while preserving order
  const seen = new Set();
  return out.filter(s => { if (seen.has(s)) return false; seen.add(s); return true; });
}

function generatedMonitoring(state, note) {
  const dxId = state.diagnosis?.id || "other";
  const out = [];
  // Body weight goal — uses RD-editable target/timeline
  const wtTarget = note.weightTarget?.trim();
  const wtLine = wtTarget
    ? `Body weight: target ${wtTarget} over ${note.weightTimeline || "12 weeks"}`
    : `Body weight trend at follow-up (target individualized over ${note.weightTimeline || "12 weeks"})`;
  out.push(wtLine);
  out.push(...(DX_MONITORING[dxId] || DX_MONITORING.other));
  out.push("24-hour or 3-day dietary recall at follow-up");
  if (state.foodSecurity && state.foodSecurity !== "secure") {
    out.push("Reassess food security status and resource utilization");
  }
  out.push(`Follow-up nutrition visit in ${note.followUp || "4–6 weeks"}`);
  return out;
}

// ---------------------------------------------------------------------------
// Sub-components
// ---------------------------------------------------------------------------
function PESBuilder({ pes, setPES, state, calc }) {
  const problemObj = PROBLEMS.find(p => p.id === pes.problem);

  return (
    <article className="doc-card pes-card">
      <header className="doc-head">
        <div className="doc-head-l">
          <span className="doc-num">A</span>
          <h3 className="doc-title">PES Statement Builder</h3>
        </div>
        <span className="badge-rec">IDNT Standard</span>
      </header>

      <div className="pes-grid">
        <div className="pes-field">
          <label className="pes-label p-color">
            <span className="pes-letter">P</span>
            <span>Problem</span>
          </label>
          <select
            className="input"
            value={pes.problem}
            onChange={e => setPES({ problem: e.target.value })}
          >
            <option value="">Select a nutrition diagnosis…</option>
            {PROBLEMS.map(p => <option key={p.id} value={p.id}>{p.label}</option>)}
          </select>
          <p className="pes-help">{PES_HELP.problem}</p>
        </div>

        <div className="pes-field">
          <label className="pes-label e-color">
            <span className="pes-letter">E</span>
            <span>Etiology</span>
          </label>
          <textarea
            className="input"
            rows={2}
            placeholder="related to…"
            value={pes.etiology}
            onChange={e => setPES({ etiology: e.target.value })}
          />
          <p className="pes-help">{PES_HELP.etiology}</p>
        </div>

        <div className="pes-field">
          <label className="pes-label s-color">
            <span className="pes-letter">S</span>
            <span>Signs &amp; Symptoms</span>
          </label>
          <textarea
            className="input"
            rows={2}
            placeholder="as evidenced by…"
            value={pes.signs}
            onChange={e => setPES({ signs: e.target.value })}
          />
          <p className="pes-help">{PES_HELP.signs}</p>
        </div>
      </div>

      {/* Live preview */}
      <div className="pes-preview" aria-label="PES statement preview">
        <span className="pes-preview-label">Preview</span>
        <div className="pes-preview-body">
          {pes.problem || pes.etiology || pes.signs ? (
            <>
              <span className="pes-block p-block">
                {problemObj ? problemObj.label : <span className="pes-ph">[problem]</span>}
              </span>
              <span className="pes-conn">related to</span>
              <span className="pes-block e-block">
                {pes.etiology.trim() || <span className="pes-ph">[etiology]</span>}
              </span>
              <span className="pes-conn">as evidenced by</span>
              <span className="pes-block s-block">
                {pes.signs.trim() || <span className="pes-ph">[signs &amp; symptoms]</span>}
              </span>
              <span className="pes-block-period">.</span>
            </>
          ) : (
            <span className="pes-empty">Choose a Problem, then add Etiology and Signs &amp; Symptoms — your statement will assemble live here.</span>
          )}
        </div>
      </div>
    </article>
  );
}

function EstimatedNeedsSection({ state, calc, derived }) {
  const d = derived;
  if (!d.ready) {
    return (
      <article className="doc-card">
        <header className="doc-head"><div className="doc-head-l"><span className="doc-num">1</span><h3 className="doc-title">Estimated Needs</h3></div></header>
        <div className="doc-empty">Awaiting demographics and anthropometrics.</div>
      </article>
    );
  }
  return (
    <article className="doc-card">
      <header className="doc-head">
        <div className="doc-head-l"><span className="doc-num">1</span><h3 className="doc-title">Estimated Needs</h3></div>
        <span className="doc-sub">From Calculation Engine · live</span>
      </header>
      <ul className="needs-list">
        <li>
          <span className="needs-label">Energy</span>
          <span className="needs-value">{fmtD(d.energyNeeds)} kcal/day</span>
          <span className="needs-meta">{d.method.label} · activity {fmtD2(d.activityMult)} · stress {fmtD2(d.stress)}{d.caloricAdj.value !== 0 ? ` · adj ${d.caloricAdj.value > 0 ? "+" : ""}${d.caloricAdj.value}` : ""}</span>
        </li>
        <li>
          <span className="needs-label">Protein</span>
          <span className="needs-value">{fmtD(d.proteinG)} g/day</span>
          <span className="needs-meta">{fmtD2(d.proteinBasis)} g/kg · {d.proteinBasisLabel} body weight{d.dxDefaults?.geriAdjusted ? " · ≥65 floor applied" : ""}</span>
        </li>
        <li>
          <span className="needs-label">Fluids</span>
          <span className="needs-value">{fmtD(d.fluid)} mL/day</span>
          <span className="needs-meta">{d.fluidMethod.label}</span>
        </li>
      </ul>
    </article>
  );
}

// (Section 2 "Nutrition Diagnosis (PES)" card removed — the PES Builder preview is the single on-screen readout;
//  the full note still assembles the PES from builder state in buildPlainNote.)

// Single-line display that flips to a textarea on click; Enter or blur commits.
function EditableLine({ value, onCommit, className, ariaLabel, autoEdit }) {
  const [editing, setEditing] = useStateDoc(!!autoEdit);
  const [draft, setDraft] = useStateDoc(value);
  const ref = useRefDoc(null);
  useEffectDoc(() => { if (!editing) setDraft(value); }, [value, editing]);
  useEffectDoc(() => {
    if (editing && ref.current) {
      const el = ref.current;
      el.focus();
      el.setSelectionRange(el.value.length, el.value.length);
      el.style.height = "auto";
      el.style.height = el.scrollHeight + "px";
    }
  }, [editing]);
  function commit() { setEditing(false); if (draft !== value) onCommit(draft); }
  if (editing) {
    return (
      <textarea
        ref={ref}
        className={`input ${className || ""}`}
        rows={1}
        value={draft}
        aria-label={ariaLabel}
        onChange={e => { setDraft(e.target.value); e.target.style.height = "auto"; e.target.style.height = e.target.scrollHeight + "px"; }}
        onBlur={commit}
        onKeyDown={e => {
          if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); commit(); }
          if (e.key === "Escape") { setDraft(value); setEditing(false); }
        }}
      />
    );
  }
  return (
    <button
      type="button"
      className={`line-display ${className || ""} ${value.trim() ? "" : "is-empty"}`}
      onClick={() => setEditing(true)}
      aria-label={`${ariaLabel} — click to edit`}
      title="Click to edit"
    >
      {value.trim() || "Click to add text…"}
    </button>
  );
}

function InterventionsSection({ state, note, setNote }) {
  const generated = generatedInterventions(state);
  const lines = note.interventionsOverride ?? generated;
  const isOverride = note.interventionsOverride != null;

  function update(idx, val) {
    const next = [...(note.interventionsOverride ?? generated)];
    next[idx] = val;
    setNote({ interventionsOverride: next });
  }
  function remove(idx) {
    const next = [...(note.interventionsOverride ?? generated)];
    next.splice(idx, 1);
    setNote({ interventionsOverride: next });
  }
  function add() {
    const next = [...(note.interventionsOverride ?? generated), ""];
    setNote({ interventionsOverride: next });
  }

  return (
    <article className="doc-card">
      <header className="doc-head">
        <div className="doc-head-l"><span className="doc-num">2</span><h3 className="doc-title">Nutrition Interventions</h3></div>
        <div className="doc-head-r">
          {isOverride && (
            <button className="link-btn" type="button" onClick={() => setNote({ interventionsOverride: null })}>
              Reset to generated
            </button>
          )}
          <span className="doc-sub">{lines.length} item{lines.length === 1 ? "" : "s"}</span>
        </div>
      </header>

      {state.diagnosis ? (
        <ol className="iv-list">
          {lines.map((line, i) => (
            <li key={i} className="iv-row">
              <span className="iv-num">{i + 1}</span>
              <EditableLine
                className="iv-text"
                value={line}
                autoEdit={line === ""}
                ariaLabel={`Intervention ${i + 1}`}
                onCommit={v => update(i, v)}
              />
              <button className="iv-x" type="button" onClick={() => remove(i)} aria-label="Remove intervention">×</button>
            </li>
          ))}
        </ol>
      ) : (
        <div className="doc-empty">Select a primary diagnosis to generate diagnosis-appropriate interventions.</div>
      )}

      {state.diagnosis && (
        <button type="button" className="iv-add" onClick={add}>
          <span>+</span> Add intervention line
        </button>
      )}
    </article>
  );
}

function MonitoringSection({ state, note, setNote, derived }) {
  const generated = generatedMonitoring(state, note);
  const lines = note.monitoringOverride ?? generated;
  const isOverride = note.monitoringOverride != null;

  function update(idx, val) {
    const next = [...(note.monitoringOverride ?? generated)];
    next[idx] = val;
    setNote({ monitoringOverride: next });
  }
  function remove(idx) {
    const next = [...(note.monitoringOverride ?? generated)];
    next.splice(idx, 1);
    setNote({ monitoringOverride: next });
  }
  function add() {
    setNote({ monitoringOverride: [...(note.monitoringOverride ?? generated), ""] });
  }

  return (
    <article className="doc-card">
      <header className="doc-head">
        <div className="doc-head-l"><span className="doc-num">3</span><h3 className="doc-title">Monitoring &amp; Evaluation</h3></div>
        <div className="doc-head-r">
          {isOverride && (
            <button className="link-btn" type="button" onClick={() => setNote({ monitoringOverride: null })}>
              Reset to generated
            </button>
          )}
        </div>
      </header>

      {/* Editable targets row */}
      <div className="me-targets">
        <label className="me-target">
          <span className="me-label">Target</span>
          <input
            type="text"
            className="input"
            placeholder="e.g. −5 kg or maintain"
            value={note.weightTarget}
            onChange={e => setNote({ weightTarget: e.target.value, monitoringOverride: null })}
          />
        </label>
        <label className="me-target">
          <span className="me-label">Timeline</span>
          <input
            type="text"
            className="input"
            value={note.weightTimeline}
            onChange={e => setNote({ weightTimeline: e.target.value, monitoringOverride: null })}
          />
        </label>
        <label className="me-target">
          <span className="me-label">Follow-up</span>
          <input
            type="text"
            className="input"
            value={note.followUp}
            onChange={e => setNote({ followUp: e.target.value, monitoringOverride: null })}
          />
        </label>
      </div>

      <ul className="me-list">
        {lines.map((line, i) => (
          <li key={i} className="me-row">
            <span className="me-bullet">•</span>
            <EditableLine
              className="me-text"
              value={line}
              autoEdit={line === ""}
              ariaLabel={`Monitoring item ${i + 1}`}
              onCommit={v => update(i, v)}
            />
            <button className="iv-x" type="button" onClick={() => remove(i)} aria-label="Remove">×</button>
          </li>
        ))}
      </ul>

      <button type="button" className="iv-add" onClick={add}>
        <span>+</span> Add monitoring line
      </button>
    </article>
  );
}

// ---------------------------------------------------------------------------
// Full Note Output (monospace plaintext panel)
// ---------------------------------------------------------------------------
function buildPlainNote({ state, derived, pes, interventions, monitoring }) {
  const d = derived;
  const today = new Date().toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
  const parts = [];

  parts.push("OUTPATIENT NUTRITION ASSESSMENT NOTE");
  parts.push(`Date: ${today}`);
  parts.push("");

  // ASSESSMENT SUMMARY
  const summaryLines = [];
  const demoBits = [];
  if (state.age) demoBits.push(`${state.age} y`);
  if (state.sex) demoBits.push(state.sex === "F" ? "Female" : state.sex === "M" ? "Male" : state.sex);
  if (demoBits.length) summaryLines.push(`Patient: ${demoBits.join(", ")}`);
  if (state.diagnosis) summaryLines.push(`Primary Dx: ${state.diagnosis.label}`);
  if (state.comorbidities?.length) summaryLines.push(`Comorbidities: ${state.comorbidities.join(", ")}`);
  if (Number.isFinite(d.heightCm) && Number.isFinite(d.weightKg)) {
    summaryLines.push(`Anthropometrics: ${fmtD1(d.heightCm)} cm, ${fmtD1(d.weightKg)} kg, BMI ${Number.isFinite(d.bmi) ? d.bmi.toFixed(1) : "—"}${d.bmiSt ? ` (${d.bmiSt.label})` : ""}`);
  }
  if (state.weightHistory?.trim()) summaryLines.push(`Weight history: ${state.weightHistory.trim()}`);
  if (d.activityRow) summaryLines.push(`Activity: ${d.activityRow.label} (multiplier ${fmtD3(d.activityMult)})`);
  if (state.foodSecurity) {
    const fs = FOOD_SECURITY.find(f => f.id === state.foodSecurity);
    if (fs) summaryLines.push(`Food security: ${fs.label}`);
  }
  if (state.labs?.trim()) summaryLines.push(`Relevant labs: ${state.labs.trim().replace(/\s+/g, " ")}`);
  if (state.dietNotes?.trim()) summaryLines.push(`Diet history: ${state.dietNotes.trim()}`);
  if (state.feedingAssistance) summaryLines.push("Feeding assistance required.");
  if (state.advanceDirectives) summaryLines.push("Advance directives noted.");
  if (state.interpreter) summaryLines.push(`Interpreter needed${state.interpreterLang ? ` (${state.interpreterLang})` : ""}.`);

  if (summaryLines.length) {
    parts.push("— ASSESSMENT SUMMARY —");
    parts.push(...summaryLines);
    parts.push("");
  }

  // ESTIMATED NEEDS
  if (d.ready) {
    parts.push("— ESTIMATED NEEDS —");
    parts.push(`Energy: ${fmtD(d.energyNeeds)} kcal/day  (${d.method.label}; activity ${fmtD3(d.activityMult)}, stress ${fmtD2(d.stress)}${d.caloricAdj.value !== 0 ? `, adjustment ${d.caloricAdj.value > 0 ? "+" : ""}${d.caloricAdj.value} kcal` : ""})`);
    if (Number.isFinite(d.proteinG)) {
      const basisTxt = `${fmtD2(d.proteinBasis)} g/kg ${d.proteinBasisLabel} body weight`;
      const ibwTxt = d.proteinBasisLabel !== "current" && Number.isFinite(d.ibw) ? `; IBW ${fmtD1(d.ibw)} kg${d.proteinBasisLabel === "adjusted" ? `, ABW ${fmtD1(d.abw)} kg` : ""}` : "";
      const geriTxt = d.dxDefaults?.geriAdjusted ? "; geriatric floor applied" : "";
      parts.push(`Protein: ${fmtD(d.proteinG)} g/day  (${basisTxt}${proteinPositionText(d)}${ibwTxt}${geriTxt})`);
      RD.modifierNoteLines(state).forEach(l => parts.push(`  ${l}`));
    }
    if (Number.isFinite(d.fluid)) {
      parts.push(`Fluids: ${fmtD(d.fluid)} mL/day  (${d.fluidMethod.label})`);
    }
    parts.push("");
  }

  // PES
  const problemObj = PROBLEMS.find(p => p.id === pes.problem);
  if (problemObj || pes.etiology.trim() || pes.signs.trim()) {
    parts.push("— NUTRITION DIAGNOSIS (PES) —");
    parts.push(
      `${problemObj ? problemObj.label : "[problem]"} related to ${pes.etiology.trim() || "[etiology]"} as evidenced by ${pes.signs.trim() || "[signs & symptoms]"}.`
    );
    parts.push("");
  }

  // Interventions
  if (interventions.length) {
    parts.push("— NUTRITION INTERVENTIONS —");
    interventions.forEach((line, i) => {
      if (line.trim()) parts.push(`${i + 1}. ${line.trim()}`);
    });
    parts.push("");
  }

  // Monitoring
  if (monitoring.length) {
    parts.push("— MONITORING & EVALUATION —");
    monitoring.forEach(line => {
      if (line.trim()) parts.push(`• ${line.trim()}`);
    });
    parts.push("");
  }

  return parts.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd();
}

function FullNoteOutput({ noteText }) {
  const [copied, setCopied] = useStateDoc(false);
  const tref = useRefDoc(null);

  async function copyAll() {
    try {
      await navigator.clipboard.writeText(noteText);
    } catch {
      // Fallback — select & copy via the hidden textarea ref.
      // Wrapped so a missing .select() (or sandbox block) can't swallow the toast.
      try {
        if (tref.current && typeof tref.current.select === "function") {
          tref.current.select();
          document.execCommand("copy");
          tref.current.blur();
        }
      } catch (_) {
        // swallow — toast still fires below so the user gets feedback
      }
    }
    setCopied(true);
    setTimeout(() => setCopied(false), 1800);
  }

  const lineCount = noteText.split("\n").length;

  return (
    <aside className="note-panel" aria-label="Full note output">
      <header className="np-head">
        <div className="np-head-l">
          <span className="np-title">Full note output</span>
          <span className="np-sub">EHR paste-ready · plaintext</span>
        </div>
        <button
          type="button"
          className={`copy-btn ${copied ? "copied" : ""}`}
          onClick={copyAll}
          disabled={!noteText.trim()}
        >
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            {copied ? (
              <polyline points="20 6 9 17 4 12"/>
            ) : (
              <>
                <rect x="9" y="9" width="13" height="13" rx="2"/>
                <path d="M5 15V5a2 2 0 0 1 2-2h10"/>
              </>
            )}
          </svg>
          <span>{copied ? "Copied" : "Copy All"}</span>
        </button>
      </header>
      <div className="np-meta">
        <span>{lineCount} line{lineCount === 1 ? "" : "s"}</span>
        <span className="np-dot">·</span>
        <span>{noteText.length.toLocaleString()} chars</span>
      </div>
      <pre className="np-body" ref={tref} tabIndex={0}>
        {noteText.trim()
          ? noteText
          : "Note will assemble automatically as you fill out the chart and PES statement above."}
      </pre>
    </aside>
  );
}

// ---------------------------------------------------------------------------
// Main Documentation zone
// ---------------------------------------------------------------------------
function Documentation({ state, calc, pes, setPES, note, setNote }) {
  const derived = useMemoDoc(() => deriveNote(state, calc), [state, calc]);

  // Auto-seed PES when diagnosis becomes available and PES is fully empty
  const [seededDx, setSeededDx] = useStateDoc(null);
  useEffectDoc(() => {
    const dx = state.diagnosis?.id;
    if (dx && dx !== seededDx && !pes.problem && !pes.etiology && !pes.signs) {
      const seed = seedPES(state, calc);
      setPES(seed);
      setSeededDx(dx);
    }
  }, [state.diagnosis?.id, pes, state.labs]);

  const interventions = useMemoDoc(() => note.interventionsOverride ?? generatedInterventions(state), [state, note.interventionsOverride]);
  const monitoring = useMemoDoc(() => note.monitoringOverride ?? generatedMonitoring(state, note), [state, note]);

  const noteText = useMemoDoc(
    () => buildPlainNote({ state, derived, pes, interventions, monitoring }),
    [state, derived, pes, interventions, monitoring]
  );

  return (
    <section className="zone" aria-labelledby="zone-docs">
      <header className="zone-head">
        <span className="zone-num">03</span>
        <h2 id="zone-docs" className="zone-title">Documentation Drafts</h2>
        <span className="zone-sub">PES Builder · 3-section note · EHR-ready output</span>
      </header>

      <div className="zone-body docs-grid">
        <div className="docs-col">
          <PESBuilder pes={pes} setPES={setPES} state={state} calc={calc} />
          <EstimatedNeedsSection state={state} calc={calc} derived={derived} />
          <InterventionsSection state={state} note={note} setNote={setNote} />
          <MonitoringSection state={state} note={note} setNote={setNote} derived={derived} />
          {/* Inline note — shown only below 1280px (CSS); above that the note lives in the right rail */}
          <div className="note-inline">
            <FullNoteOutput noteText={noteText} />
          </div>
        </div>
      </div>
    </section>
  );
}

// Shared note-text builder so the right-rail panel reads the same string as the inline one.
function computeNoteText(state, calc, pes, note) {
  const derived = deriveNote(state, calc);
  const interventions = note.interventionsOverride ?? generatedInterventions(state);
  const monitoring = note.monitoringOverride ?? generatedMonitoring(state, note);
  return buildPlainNote({ state, derived, pes, interventions, monitoring });
}

window.Documentation = Documentation;
window.FullNoteOutput = FullNoteOutput;
window.computeNoteText = computeNoteText;
