/* ═══════════════════════════════════════════════════════════
   OpAgent Inside — Physician Console (nimble two-column)
   Default Physician view. Carlos Rivera in full; others await.
   ═══════════════════════════════════════════════════════════ */

function ScopeIc({ size=18, on }){
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" className="rr-scope" style={{opacity:on?1:undefined}}>
      <circle cx="12" cy="12" r="8.5" stroke="#163D2B" strokeWidth="1.4"/>
      <line x1="12" y1="1.5" x2="12" y2="6" stroke="#163D2B" strokeWidth="1.4"/>
      <line x1="12" y1="18" x2="12" y2="22.5" stroke="#163D2B" strokeWidth="1.4"/>
      <line x1="1.5" y1="12" x2="6" y2="12" stroke="#163D2B" strokeWidth="1.4"/>
      <line x1="18" y1="12" x2="22.5" y2="12" stroke="#163D2B" strokeWidth="1.4"/>
      <circle cx="12" cy="12" r="2.4" fill="#C4973E"/>
    </svg>
  );
}

function FRow({ label, children }){
  return <div className="frow"><div className="flabel">{label}</div><div className="fval">{children}</div></div>;
}

/* ── one procedure card (CodeIQ → AuthCheck → Gap → BloQ → confirm/handoff) ── */
function ProcCard({ p, idx, live, day, onPickDay, confirmed, onConfirm, sent, sending, onSendAdmin }){
  const codeParts = String(p.code || "").split(" · ");
  const picked = (p.pickDays || []).find((d)=>d.date===day);
  const stamp = picked ? (picked.iso || picked.date) : (live ? (day || "—") : "2026-"+day);
  const gapItems = p.gapItems || [];
  return (
    <div className="step-card">
      <div className="step-head">
        <span className="eng codeiq">CODEIQ</span>
        <span className="step-title">{p.title}</span>
        <span className="step-n">{p.step}</span>
      </div>
      <div className="step-body">
        <FRow label="Documented">
          <span className="em-strong">{p.documentedLabel}</span>
          {p.planned ? <span className="tag-planned">planned</span> : <span className="tag-planned">performed</span>}
          {p.bigTicket && <span className="tag-planned">big-ticket</span>}
          <div className="quote">"{p.quote}"</div>
        </FRow>
        <FRow label="CodeIQ"><b>{codeParts[0]}</b>{codeParts.length>1 ? " · "+codeParts.slice(1).join(" · ") : ""}</FRow>
        <FRow label="AuthCheck">
          <div className="authcheck-box">
            {p.authcheck.verdict && <span className={"verdict-chip "+(p.authcheck.verdict.tone==="ok"?"ok":"warn")}>{p.authcheck.verdict.label}</span>}
            <span>{p.authcheck.text}</span>
            {p.authcheck.source && <span className="src-tag">{p.authcheck.source}</span>}
          </div>
        </FRow>
        {p.basis && <FRow label="Basis">{p.basis}</FRow>}
        {p.paymentGate && p.paymentGate.length>0 && (
          <FRow label="Payment gate"><ul className="gate-list">{p.paymentGate.map((g,i)=><li key={i}>{g}</li>)}</ul></FRow>
        )}
        {gapItems.length>0 ? (
          <FRow label="Gap (AdminQ)">
            {p.gapChecked && <div style={{fontFamily:"var(--fm)",fontSize:11,color:"var(--ink-soft)",marginBottom:6}}>checked: {p.gapChecked}</div>}
            <div className="gap-list">
              {gapItems.map((g,i)=>(
                <div key={i} className={"gap-row miss"+(g.severity==="warn"?" warn":"")}>
                  <span className="gap-ic">!</span>
                  <div className="gap-main"><div className="gap-req">{g.missing}</div><div className="gap-found">{g.why}</div></div>
                </div>
              ))}
            </div>
          </FRow>
        ) : p.bigTicket ? (
          <FRow label="Gap (AdminQ)">
            <span style={{color:"var(--forest)",fontFamily:"var(--fm)",fontSize:12.5}}>✓ No documentation gaps detected for PA.</span>
            {p.gapChecked && <div style={{fontFamily:"var(--fm)",fontSize:11,color:"var(--ink-soft)",marginTop:4}}>checked: {p.gapChecked}</div>}
          </FRow>
        ) : null}
        {p.spacing && (
          <FRow label="Spacing"><b>{p.spacing.headline}</b><div className="verify" style={{marginTop:6}}>{p.spacing.detail}</div></FRow>
        )}
        {p.denialBenchmark ? (
          <FRow label="Denial benchmark">
            <div className="bench"><b>{p.denialBenchmark.n} denial(s) · {p.denialBenchmark.atRisk} at risk</b> <span className="bench-src">— {p.denialBenchmark.source}</span></div>
            {p.verify && <div className="verify" style={{marginTop:8}}>{p.verify}</div>}
          </FRow>
        ) : (p.verify && <FRow label="Verify">{p.verify}</FRow>)}
        {p.bloq && p.bloq.bars && p.bloq.bars.length>0 && (
          <FRow label="BloQ">
            <div className="bloq-text">{p.bloq.text}</div>
            <div className="bloq-bars">
              {p.bloq.bars.map((b,i)=>(
                <div key={i} className="bloq-row">
                  <span className="bl-lab">{b.label}</span>
                  <span className="bl-track">
                    <span className="bl-fill" style={{width:b.current+"%"}}></span>
                    <span className="bl-target" style={{left:b.target+"%"}}></span>
                  </span>
                  <span className="bl-val">{b.current}% / {b.target}%</span>
                </div>
              ))}
            </div>
          </FRow>
        )}
        {p.pickDays && p.pickDays.length>0 && (
          <FRow label="Pick day">
            <div className="daypick">
              {p.pickDays.map((d,i)=>(
                <button key={i} className={day===d.date?"on":""} onClick={()=>onPickDay(d.date)} title={d.rationale||""}>
                  <div className="dw">{d.dow}</div><div className="dd">{d.date}</div>
                </button>
              ))}
            </div>
          </FRow>
        )}
        <div className="step-foot">
          <button className={"btn-confirm"+(confirmed?" done":"")} onClick={onConfirm}>
            {confirmed ? "✓ Confirmed" : "Confirm code"+(p.planned ? " + day" : "")}
          </button>
          <button className={"btn-prep"+(sent?" done":"")} disabled={sending} onClick={onSendAdmin}>
            {sent ? "✓ Sent to Admin" : (sending ? "Sending…" : "Send to Admin prep")}
          </button>
          <span className="day-stamp">day: {stamp}</span>
        </div>
      </div>
    </div>
  );
}

/* ── the right-hand deep workup (live cascade-driven, seed fallback) ── */
function RiveraWorkup({ r, onStage, onSendToAdmin, onRefresh }){
  r = r || window.DEMO_PHYS.rivera;
  const live = !!r.__live;
  const procs = r.procedures || (r.procedure ? [r.procedure] : []);
  const [dayMap, setDayMap] = useState(()=>{ const m={}; procs.forEach((p,i)=>{ m[i] = (p.pickDays && p.pickDays[0]) ? p.pickDays[0].date : ""; }); return m; });
  const [confirmMap, setConfirmMap] = useState({});
  const [sentMap, setSentMap] = useState({});
  const [sendingMap, setSendingMap] = useState({});
  const cov = String(r.coverage || "").split(" · ");
  const verdict = String((r.em && r.em.verdict) || "").split(" · ");

  function confirmProc(i, p){
    if(confirmMap[i]) return;
    setConfirmMap((m)=>({...m,[i]:true}));
    onStage({label:(p._cpt||p.title)+" confirmed"});
  }

  async function sendAdmin(i, p){
    const picked = (p.pickDays||[]).find((d)=>d.date===dayMap[i]);
    const surgeryDay = picked ? (picked.iso || picked.date) : undefined;
    if(p.planned && p.pickDays && p.pickDays.length && !surgeryDay){
      onStage({label:"Pick a BloQ surgery day before sending to Admin"});
      return;
    }
    if(live && r._appointmentId){
      setSendingMap((m)=>({...m,[i]:true}));
      const payload = {
        appointmentId: r._appointmentId,
        patientRef: r._patientRef,
        scheduleDate: r._date,
        procedureIndex: (p._index!=null ? p._index : i),
        surgeryDay,
        row: r._row,
        cpt: p._cpt,
        modifiers: p._modifiers || [],
        payer: p._payer || (r._row && r._row.payer),
        procedureName: p._procedureName || p.title,
        confirmed: true,
      };
      const res = await window.Adapters.adminTag(payload);
      setSendingMap((m)=>({...m,[i]:false}));
      if(res && !res.error){
        setSentMap((m)=>({...m,[i]:true}));
        onSendToAdmin && onSendToAdmin({
          id: r._appointmentId, time: (r._row && r._row.start ? String(r._row.start).slice(11,16) : ""),
          name: r.patientName, payer: p._payer || (r._row && r._row.payer) || "",
          procedure: (p._procedureName||p.title)+(p._cpt?" · "+p._cpt:""), sentBy: (r._row && r._row.provider) || "Provider",
        });
        onStage({label:(p._procedureName||p.title)+" sent to Admin prep"});
      } else {
        onStage({label:"Admin sync failed — "+((res&&res.error)||"retry")});
      }
    } else {
      setSentMap((m)=>({...m,[i]:true}));
      onSendToAdmin && onSendToAdmin({ id:"rivera", time:"09:00", name:"Carlos J. Rivera", payer:r.payer||"Medicare NY-Downstate 13202", procedure:"RFA L3–L5 · 64635 + 50", sentBy:"Dr. Liabaud" });
    }
  }

  return (
    <div className="detail">

      {/* patient header */}
      <div className="pt-card">
        <div className="pt-head">
          <span className="cache">{r.cache}</span>
          <span className="pt-name">{r.patientName || "Carlos J. Rivera"}</span>
          <span className="pill planned">{r.plannedCount} planned</span>
          <span className="pill em">E/M {r.emCode}</span>
          <span className="cached-at">{r.cachedAt}</span>
          <button className="update" onClick={()=> onRefresh ? onRefresh() : onStage({label:"Re-read chart"})}>↻ Update</button>
        </div>
        <div className="pt-body">
          <FRow label="Coverage"><b>{cov[0]}</b>{cov.length>1 ? " · "+cov.slice(1).join(" · ") : ""}</FRow>
          <FRow label="Note">{r.noteState}</FRow>
          <FRow label="Preview"><div className="note-preview">{r.notePreview}</div></FRow>
        </div>
      </div>

      {/* CliniQ E/M */}
      <div className="step-card">
        <div className="step-head">
          <span className="eng cliniq">CLINIQ</span>
          <span className="step-title">E/M coding</span>
          <span className="step-n">step 1</span>
        </div>
        <div className="step-body">
          <FRow label="Verdict"><b>{verdict[0]}</b>{verdict.length>1 ? " · "+verdict.slice(1).join(" · ") : ""}</FRow>
          {r.em && r.em.documented && <FRow label="Documented">{r.em.documented}</FRow>}
        </div>
      </div>

      {/* CodeIQ procedures (live: every prospective + performed procedure) */}
      {procs.length>0 ? procs.map((p,i)=>(
        <ProcCard key={i} p={p} idx={i} live={live}
          day={dayMap[i]} onPickDay={(d)=>setDayMap((m)=>({...m,[i]:d}))}
          confirmed={!!confirmMap[i]} onConfirm={()=>confirmProc(i,p)}
          sent={!!sentMap[i]} sending={!!sendingMap[i]} onSendAdmin={()=>sendAdmin(i,p)}/>
      )) : (
        <div className="step-card"><div className="step-head"><span className="eng codeiq">CODEIQ</span><span className="step-title">Procedures</span></div>
          <div className="step-body"><div className="box-intro">No prospective procedure to book in this note.</div></div></div>
      )}

      {/* FUTURE */}
      {r.future && r.future.items && r.future.items.length>0 && (
      <div className="box-card future">
        <div className="box-head">
          <span className="tag future">FUTURE</span>
          <span className="box-title">Candidates — deferred</span>
          <span className="box-note-r">saved, not coded</span>
        </div>
        <div className="box-body">
          <div className="box-intro">{r.future.note}</div>
          {r.future.items.map((it,i)=>(
            <div key={i} className="proc-item">
              <div className="pi-top"><span className="pi-name">{it.name}</span><span className="pi-cpt">{it.cpt}</span>{it.bigTicket && <span className="tag-big">big-ticket</span>}</div>
              <div className="quote">"{it.quote}"</div>
            </div>
          ))}
        </div>
      </div>
      )}

      {/* MEMORY */}
      {r.memory && r.memory.items && r.memory.items.length>0 && (
      <div className="box-card memory">
        <div className="box-head">
          <span className="tag memory">MEMORY</span>
          <span className="box-title">Prior procedures</span>
          <span className="box-note-r">spacing only</span>
        </div>
        <div className="box-body">
          <div className="box-intro">{r.memory.note}</div>
          {r.memory.items.map((it,i)=>(
            <div key={i} className="proc-item">
              <div className="pi-top"><span className="pi-name">{it.name}</span><span className="pi-region">({it.region})</span><span className="pi-cpt">· {it.cpt}</span></div>
              <div className="pi-date">{it.date}</div>
              <div className="quote">"{it.quote}"</div>
            </div>
          ))}
        </div>
      </div>
      )}

      {/* WRITE-BACK PLAN */}
      <div className="box-card plan">
        <div className="box-head">
          <span className="tag plan">PLAN</span>
          <span className="box-title">Write-back plan</span>
        </div>
        <div className="box-body">
          <ul className="plan-steps">
            {r.writeback.steps.map((s,i)=><li key={i}><span className="ps-n">{i+1}</span><span>{s}</span></li>)}
          </ul>
        </div>
      </div>

    </div>
  );
}

/* ── awaiting-workup placeholder for non-built patients ── */
function AwaitingWorkup({ pt, onRun }){
  return (
    <div className="detail">
      <div className="awaiting">
        <div className="aw-scope"><ScopeIc size={44}/></div>
        <h3>Awaiting workup — <span className="aw-name">{pt.name}</span></h3>
        <p>The chart is cached but the engines haven't been run for this encounter yet. Select to run CliniQ, CodeIQ and AuthCheck against the note.</p>
        <div className="aw-meta">
          <span>{pt.time}</span><span>{pt.payer}</span><span>{pt.complaint}</span>
        </div>
        <button className="aw-run" onClick={onRun}>Run engines for this patient →</button>
      </div>
    </div>
  );
}

/* ── loading / reconnect / error states for the live workup column ── */
function WorkupLoading({ pt }){
  return (
    <div className="detail">
      <div className="awaiting">
        <div className="aw-scope"><ScopeIc size={44}/></div>
        <h3>Running engines — <span className="aw-name">{pt && pt.name}</span></h3>
        <p>note → E/M → procedure → CodeIQ → AuthCheck → Gap → BloQ. Cached encounters open instantly; a fresh chart takes a moment.</p>
        <div className="aw-meta"><span>{pt && pt.time}</span><span>{pt && pt.payer}</span><span>{pt && pt.complaint}</span></div>
      </div>
    </div>
  );
}
function WorkupMessage({ title, body, onRetry, retryLabel }){
  return (
    <div className="detail">
      <div className="awaiting">
        <div className="aw-scope"><ScopeIc size={44}/></div>
        <h3>{title}</h3>
        <p>{body}</p>
        {onRetry && <button className="aw-run" onClick={onRetry}>{retryLabel||"Retry"} →</button>}
      </div>
    </div>
  );
}

function PhysicianConsole({ onStage, onSendToAdmin }){
  const [D, setD] = useState(window.DEMO_PHYS);
  const live = !!D.__live;
  const [date, setDate] = useState(D.__date || window.Adapters.isoToday());
  const [loading, setLoading] = useState(false);
  const [loadErr, setLoadErr] = useState(null); // null | "expired" | message
  const [activeId, setActiveId] = useState(D.schedule[0] ? D.schedule[0].id : null);
  const [watch, setWatch] = useState(D.day.liveWatch);
  const [ready, setReady] = useState({});      // appointmentId -> migrated/cached
  const [workups, setWorkups] = useState({});   // id -> { state, workup, msg }
  const pollRef = useRef(null);
  const genRef = useRef(0);                      // guards stale prefetch responses across day-loads
  const active = D.schedule.find(s=>s.id===activeId);

  // Status-first prefetch warm of a day; mark cached/ready rows; poll while
  // migrating. Mirrors chartq.js syncPrefetch — sticky server job, per-row dots,
  // never a full list re-render. Reused on first mount and on every day-load.
  function kickPrefetch(cd){
    if(pollRef.current){ clearInterval(pollRef.current); pollRef.current=null; }
    if(!cd || !cd.__live || !cd.schedule.length) return;
    const myGen = ++genRef.current;
    const rows = cd.schedule.map(s=>({ appointmentId:s.appointmentId, patientRef:s.patientRef, row:s, start:s.start, reason:s.reason, name:s.name, payer:s.payer, provider:s.provider }));
    window.Adapters.syncProviderPrefetch(cd.__date, rows).then(st=>{
      if(myGen!==genRef.current) return; // a newer day-load superseded this one
      const rd={}; st.ready.forEach(id=>rd[id]=true); setReady(rd);
      if(st.sessionExpired){ setLoadErr("expired"); return; }
      if(st.migrating){
        pollRef.current = setInterval(async()=>{
          const s2 = await window.Adapters.prefetchStatus(cd.__date);
          if(myGen!==genRef.current){ clearInterval(pollRef.current); pollRef.current=null; return; }
          const r2={}; (s2.ready||[]).forEach(id=>r2[id]=true); setReady(r2);
          const done = s2.complete || (s2.total>0 && s2.done>=s2.total);
          if(done || !s2.running || s2.sessionExpired){ clearInterval(pollRef.current); pollRef.current=null; }
        }, 2500);
      }
    });
  }

  // Load (or reload) the schedule for a date — wires the date picker / nav / Today.
  // Persists the selected day to localStorage (shared key with chartq.js) and
  // restores it on mount, so navigating away/back keeps the day + its migration.
  function loadSchedule(targetDate){
    const dt = targetDate || date || window.Adapters.isoToday();
    setLoading(true); setLoadErr(null); setDate(dt);
    try{ localStorage.setItem("opagent.inside.date", dt); }catch(e){}
    if(pollRef.current){ clearInterval(pollRef.current); pollRef.current=null; }
    genRef.current++; // invalidate any in-flight prefetch from the previous day
    window.Adapters.loadProviderDay(dt).then(res=>{
      setLoading(false);
      if(res.state==="expired"){ setLoadErr("expired"); return; }
      if(res.state!=="ready"){ setLoadErr(res.msg||"Couldn't load the schedule."); return; }
      const nd = res.console;
      window.DEMO_PHYS = nd; // keep the module mirror in sync so a tab re-mount resumes this day
      setReady({}); setWorkups({});
      setD(nd);
      setActiveId(nd.schedule[0] ? nd.schedule[0].id : null);
      kickPrefetch(nd);
    });
  }

  // Mount: restore the last-viewed day. Reuse the hydrated/loaded day when it
  // already matches (resume migration, don't refetch); otherwise load it live —
  // including the common "today is a closed/weekend day" case where hydrate left
  // the seed, so the picker is the way onto a populated day.
  useEffect(()=>{
    let saved=null;
    try{ saved=localStorage.getItem("opagent.inside.date"); }catch(e){}
    const valid = saved && /^\d{4}-\d{2}-\d{2}$/.test(saved);
    if(valid && !(live && saved===D.__date)) loadSchedule(saved);
    else if(live) kickPrefetch(D);
    else loadSchedule(date);
    return ()=>{ if(pollRef.current) clearInterval(pollRef.current); };
  },[]); // mount only

  function shiftDay(n){
    const d = new Date((date||window.Adapters.isoToday())+"T12:00:00");
    d.setDate(d.getDate()+n);
    loadSchedule(`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}-${String(d.getDate()).padStart(2,"0")}`);
  }

  // Live: load the cascade for the opened encounter (cached-preferred).
  function loadActive(refresh){
    if(!live || !active) return;
    const id = active.id;
    setWorkups(w=>({...w,[id]:{state:"loading"}}));
    const row = { appointmentId:active.appointmentId, patientRef:active.patientRef, row:active, start:active.start, name:active.name, payer:active.payer, provider:active.provider, reason:active.reason, date:D.__date };
    window.Adapters.loadWorkup(row, D.__date, refresh).then(res=>{
      setWorkups(w=>({...w,[id]:res}));
      if(res.state==="ready") setReady(rd=>({...rd,[active.appointmentId]:true}));
    });
  }
  useEffect(()=>{
    if(!live || !active) return;
    const w = workups[active.id];
    if(w && (w.state==="ready" || w.state==="loading")) return;
    loadActive(false);
  },[live, activeId]);

  const readyCount = Object.keys(ready).filter(k=>ready[k]).length;

  function renderWorkup(){
    if(loading) return <WorkupMessage title="Loading schedule…" body={"Fetching the board for "+date+"."} />;
    if(loadErr==="expired") return <WorkupMessage title="Dr. Chrono session expired" body="The live session needs a supervised sign-in. Use Reconnect on the landing screen, then retry the day." onRetry={()=>loadSchedule(date)} retryLabel="Retry"/>;
    if(loadErr) return <WorkupMessage title="Couldn't load the schedule" body={loadErr} onRetry={()=>loadSchedule(date)} retryLabel="Retry"/>;
    if(!active) return <WorkupMessage title="Nothing on the board" body={"No encounters scheduled for "+date+"."} />;
    if(!live){
      return active.ready
        ? <RiveraWorkup r={window.DEMO_PHYS.rivera} onStage={onStage} onSendToAdmin={onSendToAdmin}/>
        : <AwaitingWorkup pt={active} onRun={()=>onStage({label:"Engines queued for "+active.name})}/>;
    }
    const w = workups[active.id];
    if(!w || w.state==="loading") return <WorkupLoading pt={active}/>;
    if(w.state==="expired") return <WorkupMessage title="Dr. Chrono session expired" body="The live session needs a supervised sign-in before this chart can be read. Use Reconnect on the landing screen, then reopen the patient." onRetry={()=>loadActive(true)} retryLabel="Retry"/>;
    if(w.state==="error") return <WorkupMessage title="Couldn't run the cascade" body={w.msg||"The cascade request failed."} onRetry={()=>loadActive(true)} retryLabel="Retry"/>;
    return <RiveraWorkup key={active.id} r={w.workup} onStage={onStage} onSendToAdmin={onSendToAdmin} onRefresh={()=>loadActive(true)}/>;
  }

  return (
    <div className="screen">
      {/* control bar */}
      <div className="phys2-bar">
        <button className="phys2-load" disabled={loading} onClick={()=>loadSchedule(date)}>{loading?"Loading…":"Reload"}</button>
        <div className="phys2-date">
          <span className="nav" role="button" title="Previous day" style={{cursor:"pointer"}} onClick={()=>shiftDay(-1)}>‹</span>
          <input type="date" className="dt" value={date} max={window.Adapters.isoToday()}
            style={{border:"none",background:"transparent",font:"inherit",color:"inherit",cursor:"pointer",padding:0}}
            onChange={e=>{ if(e.target.value) loadSchedule(e.target.value); }}/>
          <span className="nav" role="button" title="Next day" style={{cursor:"pointer"}} onClick={()=>shiftDay(1)}>›</span>
          <button className={"today"+(date===window.Adapters.isoToday()?" on":"")} style={{cursor:"pointer",border:"none",font:"inherit"}} onClick={()=>loadSchedule(window.Adapters.isoToday())}>Today</button>
        </div>
        <button className={"phys2-watch"+(watch?" on":"")} onClick={()=>setWatch(w=>!w)}>
          <span className="wd"></span> Live-watch: {watch?"on":"off"}
        </button>
        <span className="phys2-status">{loading ? ("loading "+date+"…") : (live ? D.day.status : ("live · "+date))}</span>
      </div>

      {/* two columns */}
      <div className="phys2-grid">
        <div className="rail">
          <div className="rail-day">
            <h3>The day</h3>
            <span className="rd-sub">{D.day.appts} appts{live ? ` · migrated ${readyCount}/${D.day.appts}` : ` · migrating ${D.day.migrating}/${D.day.appts}`}</span>
          </div>
          <div className="rail-kpis">
            {D.day.kpis.map((k,i)=>(
              <div key={i} className={"rail-kpi "+k.tone}><div className="rk-v">{k.value}</div><div className="rk-l">{k.label}</div></div>
            ))}
          </div>
          <div className="rail-list">
            {D.schedule.map(s=>{
              const dot = live ? (ready[s.appointmentId] ? "done" : "queued") : s.dot;
              return (
                <button key={s.id} className={"rail-row"+(activeId===s.id?" on":"")} style={{"--accent":s.accent}} onClick={()=>setActiveId(s.id)}>
                  <div className="rr-top">
                    <span className="rr-time">{s.time}</span>
                    <span className="rr-name">{s.name}</span>
                    <ScopeIc size={16} on={activeId===s.id}/>
                    <span className={"rr-dot "+dot}></span>
                  </div>
                  <span className="rr-payer">{s.payer}</span>
                  <div className="rr-comp">{s.complaint}</div>
                </button>
              );
            })}
          </div>
        </div>

        {renderWorkup()}
      </div>
    </div>
  );
}

/* ── module wrapper with Console / Cards toggle ── */
function PhysicianModule({ onStage, onSendToAdmin }){
  const [view, setView] = useState("console");
  return (
    <div className="screen">
      <div className="mod-intro">
        <div><h2>Provider</h2></div>
        <div className="seg" style={{transform:"scale(.92)",transformOrigin:"right center"}}>
          <button className={view==="console"?"on":""} onClick={()=>setView("console")}>Console</button>
          <button className={view==="cards"?"on":""} onClick={()=>setView("cards")}>Cards</button>
        </div>
      </div>
      {view==="console" ? <PhysicianConsole onStage={onStage} onSendToAdmin={onSendToAdmin}/> : <PhysicianCards onStage={onStage}/>}
    </div>
  );
}

Object.assign(window, { PhysicianConsole, PhysicianModule, FRow, ScopeIc });
