/* ═══════════════════════════════════════════════════════════
   OpAgent | Anywhere — Eligibility tab (Build Spec v4)
   Pipeline: Soft Check (271, REUSED engine) → Portal Determination
   (NGSConnex stub) → Template fill → Patient flags → Signed note +
   writeback (Phase 2 PREVIEW, disarmed). Fail-closed PENDING CRAIG.
   ═══════════════════════════════════════════════════════════ */
(function(){
  const { useEffect, useState } = React;

  const STAGE_STATE_LABEL = {
    complete: "Complete",
    pending_craig: "PENDING CRAIG",
    preview_disabled: "Phase 2 preview",
    error: "Error",
  };
  function stageTone(state){
    if(state==="complete") return "active";
    if(state==="pending_craig") return "review";
    if(state==="error") return "error";
    return "neutral"; // preview_disabled
  }

  function isoToday(){
    const d = new Date();
    return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}-${String(d.getDate()).padStart(2,"0")}`;
  }

  function StagePill({ s }){
    return (
      <span className="wf-eligibility-result" style={{ display:"inline-flex", gap:6, alignItems:"baseline" }}>
        <span className={"wf-eligibility-pill " + stageTone(s.state)}>{s.stage}. {s.title}</span>
        <span className="wf-eligibility-details">{STAGE_STATE_LABEL[s.state] || s.state}</span>
      </span>
    );
  }

  function PipelineLegend({ stages }){
    return (
      <div className="idr-box">
        <div className="h1">Pipeline (same engine, two entry points)</div>
        <div className="muted">
          Stage 1 reuses the existing Soft Check (271) engine. Stage 2 reads the payer portal
          (NGSConnex). Stages 3–4 fill the template and derive patient flags. Stage 5 (signed note +
          writeback) is a <b>Phase 2 preview</b> — writes are disarmed in this pass.
        </div>
        <div style={{ display:"flex", gap:8, flexWrap:"wrap", marginTop:10 }}>
          {(stages||[]).map(st=>(
            <span key={st.key} className={"wf-eligibility-pill " + (st.phase2 ? "neutral" : "active")} title={st.reuse||""}>
              {st.stage}. {st.title}{st.phase2 ? " · Phase 2" : ""}{st.reuse ? " · reuses " + st.reuse : ""}
            </span>
          ))}
        </div>
      </div>
    );
  }

  function ControlsStrip({ controls, portal }){
    if(!controls) return null;
    return (
      <div style={{ display:"flex", gap:10, flexWrap:"wrap", alignItems:"center", fontFamily:"var(--fm)", fontSize:10.5, letterSpacing:".04em" }}>
        {portal && (
          <span className={"wf-eligibility-pill " + (portal.isStub ? "review" : "active")}>
            Portal: {portal.label}{portal.isStub ? " · STUB" : " · LIVE"}
          </span>
        )}
        {controls.phase2Disarmed && <span style={{ color:"#3a5f4a", fontWeight:700 }}>PHASE 2 WRITEBACK DISARMED</span>}
        {controls.externalWritesEnabled===false && <span style={{ color:"#3a5f4a" }}>NO DRCHRONO WRITEBACK</span>}
        {controls.armWrites===false && <span style={{ color:"#3a5f4a" }}>WRITES DISARMED (armWrites=0)</span>}
      </div>
    );
  }

  function PortalConnectCard(){
    const [st, setSt] = useState(null);
    const [code, setCode] = useState("");
    const [busy, setBusy] = useState(false);
    const [msg, setMsg] = useState("");
    async function ensure(){
      try {
        let s = await window.Adapters.eligibilityPortalStatus();
        // Status only — never auto-login with empty code (burns NGS 10 MFA/day cap).
        setSt(Object.assign({}, s||{}, { reconnecting:false, needsMfa: !!(s && s.needsMfa) }));
        if(s && s.connected) setMsg("Connected for today — MFA not needed again until tomorrow.");
        else if(s && s.needsMfa) setMsg(s.reason || "MFA required once today — Connect or Manual login.");
      } catch(_e){ setSt({ connected:false, sessionExists:false, needsMfa:false, reason:"status unavailable" }); }
    }
    useEffect(()=>{ ensure(); /* eslint-disable-next-line */ },[]);
    async function connect(){
      setBusy(true); setMsg("");
      try {
        const typed = (code || "").trim();
        const r = await window.Adapters.eligibilityPortalLogin(typed, { credentialWake: !typed });
        setSt(Object.assign({}, r, { needsMfa: !!(r && r.needsMfa), reconnecting:false }));
        setMsg(r.connected
          ? "Connected for today."
          : (r.needsMfa
            ? (r.reason || "Paste today's same MFA code (does not send a new email).")
            : (r.reason || r.error || "Not connected.")));
        if(r.connected) setCode("");
      } catch(e){ setMsg((e&&e.message)||"Login failed"); }
      finally { setBusy(false); }
    }
    const connected = !!(st && st.connected);
    const needsMfa = !!(st && st.needsMfa);
    const reconnecting = !!(st && st.reconnecting);
    const tone = connected ? "active" : (needsMfa ? "error" : "review");
    const label = !st ? "Checking…" : connected ? "Connected · valid today" : reconnecting ? "Restoring today's session…" : needsMfa ? "MFA once today" : "Idle";
    const credsMissing = st && st.credsConfigured === false;
    return (
      <div className="idr-box">
        <div style={{ display:"flex", gap:8, alignItems:"center", flexWrap:"wrap" }}>
          <div className="h1" style={{ margin:0 }}>NGSConnex connection</div>
          <span className={"wf-eligibility-pill " + tone}>{label}</span>
          <button className="pill-btn" onClick={ensure} disabled={busy || reconnecting}>Re-check</button>
        </div>
        <div className="muted" style={{ marginTop:6 }}>
          MFA is a <b>daily code</b> (valid until 11:59 PM EST). Connect once per day — reopening OpAgent will not ask again while today's session is good.
        </div>
        {credsMissing ? (
          <div className="muted" style={{ marginTop:8, color:"#7a1e1e" }}>
            Server credentials not configured (NGS_CONNEX_USERNAME / NGS_CONNEX_PASSWORD). Set them, then connect.
          </div>
        ) : !connected && !reconnecting ? (
          <div style={{ marginTop:10, display:"flex", gap:8, flexWrap:"wrap", alignItems:"center" }}>
            <input
              type="text"
              inputMode="numeric"
              autoComplete="one-time-code"
              placeholder="Today's same MFA code"
              value={code}
              onChange={(e)=>setCode(e.target.value)}
              onKeyDown={(e)=>{ if(e.key==="Enter" && !busy) connect(); }}
              style={{ fontFamily:"var(--fm)", fontSize:12, border:"1px solid var(--canvas-dark)", borderRadius:7, padding:"7px 9px", background:"#fff", width:170 }}
            />
            <button className={"pill-btn " + (busy ? "loading" : "")} disabled={busy} onClick={connect}
              title={code.trim() ? "Enter today's same daily MFA — does not send a new email." : "Password wake; paste MFA next if NGS challenges."}>
              {busy && <span className="wf-mini-spinner" aria-hidden="true"></span>}
              {busy ? "Connecting…" : (code.trim() ? "Submit MFA" : "Reconnect")}
            </button>
            {!!msg && <span className="wf-eligibility-details" style={{ color: connected ? "#1d5e3e" : "#7a1e1e" }}>{msg}</span>}
          </div>
        ) : (
          <div style={{ marginTop:8 }}>
            {!!msg && <span className="wf-eligibility-details" style={{ color: connected ? "#1d5e3e" : "#7a1e1e" }}>{msg}</span>}
          </div>
        )}
      </div>
    );
  }

  function GoldsetCard({ goldset }){
    if(!goldset) return null;
    return (
      <div className="idr-box">
        <div className="h1">Gold set (acceptance gate) · {goldset.collectedTotal}/{goldset.targetTotal}</div>
        <div className="muted">{goldset.shortfallSummary}</div>
        {goldset.acceptanceGate && (
          <div className="muted" style={{ marginTop:6 }}>
            Gate: ≤{Math.round(goldset.acceptanceGate.maxErrorRate*100)}% error · {Math.round(goldset.acceptanceGate.maxFalseActiveRate*100)}% false-active ·
            {" "}{Math.round(goldset.acceptanceGate.minAbstentionOnUnverifiable*100)}% abstention on unverifiable ·
            {" "}gate evaluable: <b>{goldset.gateEvaluable ? "yes" : "no (scaffold)"}</b>
          </div>
        )}
        {!!(goldset.strata && goldset.strata.length) && (
          <div style={{ marginTop:8, display:"grid", gap:4 }}>
            {goldset.strata.map(st=>(
              <div key={st.id} className="muted" style={{ display:"flex", justifyContent:"space-between", gap:10 }}>
                <span>{st.label}{st.challenge ? " · challenge" : ""}</span>
                <span style={{ color: st.shortfall>0 ? "#8A6B1E" : "#1d5e3e" }}>{st.collected}/{st.target} (short {st.shortfall})</span>
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }

  function wbStatusColor(status){
    if(status==="written" || status==="verified" || status==="noop") return "#2b6b45";
    if(status==="failed" || status==="blocked") return "#9A2A2A";
    return "#8A6B1E"; // preview / skipped
  }

  function WritebackActions({ r, row, wb, onWriteback, busyWb }){
    if(!r || !r.writeback) return null;
    const armed = !!r.writeback.armed;
    const canWrite = (r.writeback.steps||[]).some(s=>s.recommended);
    const running = wb && wb.status==="running";
    return (
      <div style={{ marginTop:8, borderTop:"1px dashed rgba(22,61,43,.15)", paddingTop:8 }}>
        <div style={{ display:"flex", gap:8, alignItems:"center", flexWrap:"wrap" }}>
          <button
            className={"pill-btn " + (running ? "loading" : "")}
            disabled={busyWb || running || !row.patientRef}
            onClick={()=>onWriteback(row)}
            title={armed ? "Executes Steps 10-12 live on the chart" : "Server is disarmed — this returns a preview (0 writes)"}
          >
            {running && <span className="wf-mini-spinner" aria-hidden="true"></span>}
            {running ? "Writing…" : (armed ? "Arm & write Steps 10-12" : "Preview writeback (disarmed)")}
          </button>
          {!canWrite && <span className="wf-eligibility-details" style={{ color:"#8A6B1E" }}>All steps HOLD — nothing recommended</span>}
        </div>
        {wb && wb.status==="error" && <div className="muted" style={{ color:"#7a1e1e", marginTop:6 }}>{wb.message}</div>}
        {wb && wb.status==="done" && wb.result && (
          <div style={{ marginTop:6, display:"grid", gap:4 }}>
            <div className="muted" style={{ textTransform:"none", letterSpacing:0 }}>
              {wb.result.armed ? "ARMED" : "DISARMED preview"} — {wb.result.message}
              {wb.result.notePreserved ? " · prior note preserved below divider" : ""}
            </div>
            {(wb.result.steps||[]).slice().sort((a,b)=>a.order-b.order).map(s=>(
              <div key={s.key} style={{ fontFamily:"var(--fm)", fontSize:11.5, color:"var(--ink)" }}>
                <span style={{ fontWeight:700, color:wbStatusColor(s.status) }}>{(s.status||"").toUpperCase()}</span>
                {" · "}{s.order}. {s.key} — {s.message}
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }

  function StageDetail({ run, row, wb, onWriteback, busyWb }){
    if(!run) return null;
    if(run.status==="running") return <div className="muted">Running pipeline…</div>;
    if(run.status==="error") return <div className="muted" style={{ color:"#7a1e1e" }}>{run.message}</div>;
    const r = run.result;
    if(!r) return null;
    return (
      <div style={{ marginTop:10, display:"grid", gap:8 }}>
        <div style={{ display:"flex", gap:8, flexWrap:"wrap", alignItems:"center" }}>
          <span className={"wf-eligibility-pill " + (r.terminalStatus==="blank" ? "active" : "review")}>
            Terminal status: {r.terminalStatus==="blank" ? "blank (ready-to-code on lock)" : r.terminalStatus}
          </span>
          <span className="wf-eligibility-details">signed by {r.signer}</span>
        </div>
        {(r.cleaning && (r.cleaning.memberId || r.cleaning.name)) && (
          <div className="muted" style={{ fontFamily:"var(--fm)", fontSize:11 }}>
            input cleaning:
            {r.cleaning.memberId ? ` member id → ${r.cleaning.memberId.value}${r.cleaning.memberId.changed ? " (" + r.cleaning.memberId.note + ")" : " (unchanged)"}` : ""}
            {r.cleaning.name ? ` · name → ${r.cleaning.name.value}${r.cleaning.name.changed ? " (" + r.cleaning.name.note + ")" : " (unchanged)"}` : ""}
          </div>
        )}
        <div style={{ display:"grid", gap:6 }}>
          {(r.stages||[]).map(s=>(
            <div key={s.key} style={{ border:"1px solid rgba(22,61,43,.10)", borderRadius:8, padding:"8px 10px", background:"#fff" }}>
              <StagePill s={s}/>
              <div className="muted" style={{ marginTop:4, textTransform:"none", letterSpacing:0 }}>{s.summary}</div>
            </div>
          ))}
        </div>
        {!!(r.pendingCraig && r.pendingCraig.length) && (
          <div className="muted" style={{ color:"#7a1e1e" }}>
            PENDING CRAIG: {r.pendingCraig.join("; ")}.
          </div>
        )}
        {!!(r.softCheckFyi && r.softCheckFyi.length) && !(r.pendingCraig && r.pendingCraig.length) && (
          <div className="muted" style={{ color:"#7a5a10" }}>
            271 FYI: {r.softCheckFyi.join("; ")}. NGS + Grid resolved — soft check does not block proposal.
          </div>
        )}
        {r.chartNote && (
          <div style={{ border:"1px solid rgba(43,107,69,.28)", borderRadius:8, padding:"8px 10px", background:"#f4faf6" }}>
            <div style={{ fontFamily:"var(--fs)", fontSize:12, fontWeight:700, color:"var(--ink)", marginBottom:5 }}>
              Note OpAgent writes to the chart — Step 10 (demographics insurance note)
            </div>
            <pre style={{ whiteSpace:"pre-wrap", fontFamily:"var(--fm)", fontSize:12, color:"var(--ink)", margin:0 }}>{r.chartNote}</pre>
          </div>
        )}
        {r.writeback && (
          <div style={{ border:"1px solid rgba(22,61,43,.10)", borderRadius:8, padding:"8px 10px", background:"#fff" }}>
            <div style={{ display:"flex", gap:8, alignItems:"center", flexWrap:"wrap", marginBottom:5 }}>
              <b style={{ fontFamily:"var(--fs)", fontSize:12, color:"var(--ink)" }}>Writeback plan — Steps 10-12</b>
              <span className={"wf-eligibility-pill " + (r.writeback.armed ? "active" : "review")}>
                {r.writeback.armed ? "ARMED" : "DISARMED preview — 0 writes"}
              </span>
            </div>
            <div style={{ display:"grid", gap:5 }}>
              {(r.writeback.steps||[]).map(st=>(
                <div key={st.key} style={{ fontFamily:"var(--fm)", fontSize:11.5, color:"var(--ink)" }}>
                  <span style={{ color: st.recommended ? "#2b6b45" : "#8A6B1E", fontWeight:700 }}>
                    {st.recommended ? "READY" : "HOLD"}
                  </span>
                  {" · "}{st.order}. {st.title} — {st.action}
                </div>
              ))}
            </div>
            <WritebackActions r={r} row={row} wb={wb} onWriteback={onWriteback} busyWb={busyWb}/>
          </div>
        )}
        <details className="idr-drawer-section">
          <summary>Full audit note (Phase 2 preview — not written)</summary>
          <pre style={{ whiteSpace:"pre-wrap", fontFamily:"var(--fm)", fontSize:11.5, color:"var(--ink)", margin:0 }}>{r.note}</pre>
        </details>
      </div>
    );
  }

  function meaningfulEligNote(note){
    const n = String(note || "").trim();
    if(n.length < 40) return false;
    if(/run eligibility to generate|dry-run preview|not read yet/i.test(n)) return false;
    return /INSURANCE TYPE\s*:|SPECIALIST COPAY|OUT-OF-POCKET\s*:|\bPCP\s*:|\bPAYER\s*:/i.test(n);
  }

  // A single, human-readable disposition tag per row — this is Craig's "did it
  // get done or not" signal. Derived from the run result + the row's status.
  function rowTag({ row, run, wb }){
    if(wb && wb.status==="done" && wb.result && wb.result.armed){
      const allOk = (wb.result.steps||[]).every(s=>["written","verified","noop"].includes(s.status));
      return allOk ? { label:"DONE", tone:"active" } : { label:"PARTIAL", tone:"review" };
    }
    if(run && run.status==="running") return { label:"RUNNING", tone:"neutral" };
    if(run && run.status==="error") return { label:"ERROR", tone:"error" };
    if(run && run.status==="done" && run.result){
      const r = run.result;
      const note = r.chartNote || r.note || "";
      if(r.pendingCraig && r.pendingCraig.length) return { label:"PENDING CRAIG", tone:"error" };
      if(r.terminalStatus==="blank" && meaningfulEligNote(note)) return { label:"PROPOSED READY", tone:"active" };
      if(meaningfulEligNote(note)) return { label:"PROPOSED", tone:"review" };
      return { label:"TO DO", tone:"neutral" };
    }
    if(row.status==="needs-human-review") return { label:"PENDING CRAIG", tone:"error" };
    return { label:"TO DO", tone:"neutral" };
  }
  function tagColor(tone){
    if(tone==="active") return { bg:"#e8f5ee", bd:"#2b6b45", fg:"#1d5e3e" };
    if(tone==="error") return { bg:"#f9ecec", bd:"#9A2A2A", fg:"#7a1e1e" };
    if(tone==="review") return { bg:"#fbf4e4", bd:"#8A6B1E", fg:"#7a5a12" };
    return { bg:"#eef1f0", bd:"#3a5f4a", fg:"#3a5f4a" };
  }

  function EligRow({ row, run, busy, onRun, wb, onWriteback, busyWb }){
    const priority = (row.priority || "").toLowerCase();
    const priColor = priority === "high" ? "#9A2A2A" : priority === "medium" ? "#8A6B1E" : "#3a5f4a";
    const running = run && run.status==="running";
    const tag = rowTag({ row, run, wb });
    const tc = tagColor(tag.tone);
    return (
      <div className="wfr" style={{ border:"1px solid rgba(22,61,43,.10)", borderRadius:10, padding:"10px 12px", background:"#fff" }}>
        <div style={{ display:"flex", justifyContent:"space-between", gap:10, alignItems:"baseline" }}>
          <div style={{ fontFamily:"var(--fs)", fontSize:13, color:"var(--ink)" }}>
            <b>{row.patientName || "Unknown patient"}</b>
            {row.dos && <span style={{ color:"var(--ink-faint)" }}> · DOS {row.dos}</span>}
            {row.claimId && <span style={{ color:"var(--ink-faint)" }}> · Claim #{row.claimId}</span>}
            {row.payer && <span style={{ color:"var(--ink-faint)" }}> · {row.payer}</span>}
          </div>
          <div style={{ display:"flex", gap:8, alignItems:"center" }}>
            <span style={{ fontFamily:"var(--fm)", fontSize:9.5, fontWeight:700, letterSpacing:".05em", textTransform:"uppercase", color:tc.fg, background:tc.bg, border:"1px solid "+tc.bd, borderRadius:6, padding:"2px 7px" }}>
              {tag.label}
            </span>
            <div style={{ fontFamily:"var(--fm)", fontSize:10, letterSpacing:".06em", textTransform:"uppercase", color:priColor }}>
              {priority || "low"}
            </div>
          </div>
        </div>
        {row.bucket && (
          <div style={{ marginTop:5, fontFamily:"var(--fm)", fontSize:10, letterSpacing:".04em", color:"var(--ink-faint)" }}>
            bucket: {row.bucket}
          </div>
        )}
        <div style={{ marginTop:6, fontFamily:"var(--fs)", fontSize:12, color:"var(--ink)" }}>
          <b>{row.title}</b> — {row.detail}
        </div>
        {row.reasonCode && (
          <div style={{ marginTop:6, fontFamily:"var(--fm)", fontSize:10, letterSpacing:".05em", textTransform:"uppercase", color:"#9A2A2A", fontWeight:700 }}>
            reason {row.reasonCode}
          </div>
        )}
        <div style={{ marginTop:8, display:"flex", gap:8, flexWrap:"wrap", alignItems:"center" }}>
          <button
            className={"pill-btn " + (running ? "loading" : "")}
            disabled={busy || running || !row.patientRef}
            onClick={()=>onRun(row)}
          >
            {running && <span className="wf-mini-spinner" aria-hidden="true"></span>}
            {running ? "Running pipeline…" : "Run eligibility pipeline"}
          </button>
          {row.patientUrl && (
            <a className="pill-btn" href={row.patientUrl} target="_blank" rel="noreferrer">Open DrChrono</a>
          )}
        </div>
        <StageDetail run={run} row={row} wb={wb} onWriteback={onWriteback} busyWb={busyWb}/>
      </div>
    );
  }

  function BucketChips({ buckets, statuses }){
    // Show every configured ELIG REQUIRED bucket (even at 0) so Craig sees the
    // whole board, matching his Live Claims Feed filter.
    const defs = (statuses && statuses.length) ? statuses.map(s=>s.label) : Object.keys(buckets||{});
    if(!defs.length) return null;
    return (
      <div style={{ display:"flex", gap:8, flexWrap:"wrap" }}>
        {defs.map(label=>{
          const n = (buckets && buckets[label]) || 0;
          return (
            <span key={label} className="wf-eligibility-pill neutral" style={{ background:"#fff" }}>
              {label} · <b>{n}</b>
            </span>
          );
        })}
      </div>
    );
  }

  window.EligibilityModule = function EligibilityModule(){
    const [data, setData] = useState(null);
    const [err, setErr] = useState("");
    const [loading, setLoading] = useState(true);
    const [view, setView] = useState("worklist"); // "worklist" (Craig's bucket) | "schedule" (surgeon's day)
    const [date, setDate] = useState(isoToday());
    const [runs, setRuns] = useState({});
    const [busyId, setBusyId] = useState("");
    const [wb, setWb] = useState({});
    const [busyWbId, setBusyWbId] = useState("");
    const [sweep, setSweep] = useState(null); // { total, done, running }
    const [coverageAll, setCoverageAll] = useState(false); // false = Medicare/NGS only (Phase 1)

    async function loadWorklist(refresh, allOverride){
      setLoading(true); setErr("");
      try {
        const all = (allOverride===undefined ? coverageAll : allOverride);
        let j = await window.Adapters.eligibilityWorklist(refresh, all);
        if(!j) j = await window.Adapters.eligibilityWorklist(false, all);
        const hasQueue = !!(j && Array.isArray(j.queue) && j.queue.length);
        if(j && (hasQueue || !j.error)){ setErr(""); setData(j); }
        else { setErr((j&&j.error) || "Worklist unavailable. Connect Dr. Chrono and retry."); if(j) setData(j); }
      } catch(_e){
        setErr("Worklist unavailable. Connect Dr. Chrono and retry.");
      } finally { setLoading(false); }
    }
    async function loadSchedule(useDate){
      setLoading(true); setErr("");
      try {
        const j = await window.Adapters.eligibilityOverview(useDate || date);
        if(!j){ setErr("Eligibility overview unavailable. Connect Dr. Chrono and retry."); }
        else { setData(j); if(j.date) setDate(j.date); }
      } catch(_e){
        setErr("Eligibility overview unavailable. Connect Dr. Chrono and retry.");
      } finally { setLoading(false); }
    }
    function load(opts){
      const o = opts || {};
      if(view==="worklist") return loadWorklist(!!o.refresh);
      return loadSchedule(o.date || date);
    }
    useEffect(()=>{ if(view==="worklist") loadWorklist(false); else loadSchedule(date); /* eslint-disable-next-line */ },[view]);

    async function onRun(row){
      setBusyId(row.id);
      setRuns(m=>Object.assign({}, m, { [row.id]: { status:"running" } }));
      let outcome = { status:"error" };
      try {
        const r = await window.Adapters.eligibilityRun(row.id, {
          patientRef: row.patientRef,
          appointmentId: row.claimId,
          payer: row.payer,
          patientName: row.patientName,
        });
        if(!r || r.error){
          outcome = { status:"error", message:(r&&r.error)||"Pipeline failed" };
        } else {
          outcome = { status:"done", result:r.result };
        }
      } catch(e){
        outcome = { status:"error", message:(e&&e.message)||"Pipeline failed" };
      } finally {
        setRuns(m=>Object.assign({}, m, { [row.id]: outcome }));
        setBusyId("");
      }
      return outcome;
    }

    // Run-the-queue sweep (DRY-PROPOSE): run the pipeline for every actionable
    // item sequentially. Nothing is written — this proposes a determination per
    // patient and surfaces abstentions as PENDING CRAIG, exactly matching Craig's
    // "work the whole bucket" pass. Writes stay per-item + guarded.
    async function runQueue(rows){
      const todo = (rows||[]).filter(r=>r.patientRef && r.status!=="needs-human-review");
      if(!todo.length) return;
      setSweep({ total: todo.length, done: 0, running: true });
      for(let i=0;i<todo.length;i++){
        await onRun(todo[i]);
        setSweep({ total: todo.length, done: i+1, running: i+1<todo.length });
      }
      setSweep(s=>s ? Object.assign({}, s, { running:false }) : s);
    }

    async function onWriteback(row){
      setBusyWbId(row.id);
      setWb(m=>Object.assign({}, m, { [row.id]: { status:"running" } }));
      try {
        const r = await window.Adapters.eligibilityWriteback(row.id, {
          patientRef: row.patientRef,
          appointmentId: row.claimId,
          payer: row.payer,
          patientName: row.patientName,
        });
        if(!r || r.error){
          setWb(m=>Object.assign({}, m, { [row.id]: { status:"error", message:(r&&(r.error||r.reason))||"Writeback failed" } }));
        } else {
          setWb(m=>Object.assign({}, m, { [row.id]: { status:"done", result:r.writeback } }));
        }
      } catch(e){
        setWb(m=>Object.assign({}, m, { [row.id]: { status:"error", message:(e&&e.message)||"Writeback failed" } }));
      } finally {
        setBusyWbId("");
      }
    }

    if(loading && !data) return <div className="login-load"><div className="ring"></div><div className="lt">Loading eligibility worklist…</div></div>;
    const d = data || { queue:[], stages:[], controls:{}, portal:{}, goldset:null, meta:{}, buckets:{}, statuses:[] };
    const queue = Array.isArray(d.queue) ? d.queue : [];
    const isWorklist = view==="worklist";
    const readyCount = queue.filter(r=>r.status!=="needs-human-review").length;
    const pendingCount = queue.filter(r=>r.status==="needs-human-review").length;

    return (
      <div className="module">
        <div className="idr-wrap">
          <div className="idr-moneyline">
            <div className="idr-kicker">Eligibility</div>
            <div className="idr-head">
              {queue.length} {isWorklist ? "pending-eligibility item" : "eligibility-required item"}{queue.length===1?"":"s"}
              {" · "}NGSConnex ({d.portal && d.portal.isStub===false ? "live" : "stub"}) determination read
            </div>
            <div className="idr-sub">
              {isWorklist
                ? "Craig's daily bucket — the Live Claims Feed filtered to the ELIG REQUIRED statuses, back to the beginning of time. Independent of the surgeon's schedule."
                : "Today's surgeon schedule, classified for eligibility. Soft Check confirms active/plan/member/group/start only — the portal carries Craig's five determinations."}
            </div>
          </div>

          {!!err && <div className="datamode-banner" style={{ background:"rgba(154,42,42,.08)", border:"1px solid rgba(154,42,42,.28)", color:"#7a1e1e" }}>{err}</div>}

          <div style={{ display:"flex", gap:8, flexWrap:"wrap", alignItems:"center" }}>
            <div style={{ display:"inline-flex", border:"1px solid var(--canvas-dark)", borderRadius:8, overflow:"hidden" }}>
              <button className="pill-btn" style={{ borderRadius:0, border:"none", background: isWorklist ? "var(--ink)" : "#fff", color: isWorklist ? "#fff" : "var(--ink)" }} onClick={()=>setView("worklist")}>Craig's worklist</button>
              <button className="pill-btn" style={{ borderRadius:0, border:"none", background: !isWorklist ? "var(--ink)" : "#fff", color: !isWorklist ? "#fff" : "var(--ink)" }} onClick={()=>setView("schedule")}>Today's schedule</button>
            </div>
            {isWorklist ? (
              <button className="pill-btn" onClick={()=>loadWorklist(true)} disabled={loading} title="Re-scrape the ELIG REQUIRED bucket from the Live Claims Feed (slow)">
                {loading ? "Refreshing…" : "Refresh bucket"}
              </button>
            ) : (
              <>
                <input
                  type="date"
                  value={date}
                  onChange={(e)=>{ setDate(e.target.value); loadSchedule(e.target.value); }}
                  style={{ fontFamily:"var(--fm)", fontSize:11, border:"1px solid var(--canvas-dark)", borderRadius:7, padding:"7px 8px", background:"#fff" }}
                />
                <button className="pill-btn" onClick={()=>loadSchedule(isoToday())}>Today</button>
                <button className="pill-btn" onClick={()=>loadSchedule(date)}>Refresh</button>
              </>
            )}
            <ControlsStrip controls={d.controls} portal={d.portal}/>
          </div>

          <PortalConnectCard/>

          <PipelineLegend stages={d.stages}/>

          <div className="idr-box">
            <div style={{ display:"flex", gap:10, alignItems:"center", flexWrap:"wrap" }}>
              <div className="h1" style={{ margin:0 }}>{isWorklist ? "Eligibility worklist" : "Eligibility-required queue"}</div>
              <span className="wf-eligibility-pill active" style={{ background:"#fff" }}>{readyCount} to work</span>
              {pendingCount>0 && <span className="wf-eligibility-pill error" style={{ background:"#fff" }}>{pendingCount} PENDING CRAIG</span>}
              <button
                className={"pill-btn " + (sweep && sweep.running ? "loading" : "")}
                disabled={(sweep && sweep.running) || !readyCount}
                onClick={()=>runQueue(queue)}
                title="Run the pipeline for every item (DRY-PROPOSE — no writes). Abstentions surface as PENDING CRAIG."
              >
                {sweep && sweep.running && <span className="wf-mini-spinner" aria-hidden="true"></span>}
                {sweep && sweep.running ? `Running queue… ${sweep.done}/${sweep.total}` : "Run the queue (dry)"}
              </button>
              {sweep && !sweep.running && sweep.total>0 && (
                <span className="wf-eligibility-details">swept {sweep.done}/{sweep.total}</span>
              )}
            </div>
            {isWorklist && d.benchmark && d.benchmark.mode==="scoped" && (
              <div style={{ marginTop:8, padding:"8px 12px", borderRadius:10, background:"rgba(180,120,20,.08)", border:"1px solid rgba(180,120,20,.35)", fontFamily:"var(--fs)", fontSize:12, color:"#7a5210" }}>
                <b>Benchmark mode</b> · scope: {(d.benchmark.bucketCodes||[]).join(", ")} · DOS ≥ {d.benchmark.minDos} · OpAgent writes its note but <b>does not change the billing status</b> (the eligibility rep reviews & overwrites). {d.benchmark.droppedOutOfScope>0 ? `${d.benchmark.droppedOutOfScope} out-of-scope item(s) hidden.` : ""}
              </div>
            )}
            {isWorklist && <div style={{ marginTop:8 }}><BucketChips buckets={d.buckets} statuses={d.statuses}/></div>}
            {isWorklist && d.coverage && (
              <div style={{ marginTop:8, display:"flex", gap:10, flexWrap:"wrap", alignItems:"center" }}>
                <span className="wf-eligibility-pill active" style={{ background:"#fff" }}>{d.coverage.live} live-determinable (Medicare)</span>
                {d.coverage.hidden>0 && (
                  <span className="wf-eligibility-pill review" style={{ background:"#fff" }} title={Object.entries(d.coverage.hiddenByPayer||{}).map(([p,n])=>`${p}: ${n}`).join(" · ")}>
                    {d.coverage.hidden} hidden — no live portal yet
                  </span>
                )}
                <label style={{ display:"inline-flex", gap:6, alignItems:"center", fontFamily:"var(--fm)", fontSize:11, color:"var(--ink-faint)", cursor:"pointer" }}>
                  <input type="checkbox" checked={coverageAll} onChange={(e)=>{ setCoverageAll(e.target.checked); loadWorklist(false, e.target.checked); }}/>
                  Show all payers (incl. not-yet-covered)
                </label>
              </div>
            )}
            <div className="muted" style={{ marginTop:8 }}>
              {isWorklist
                ? "Phase 1 shows only payers we can determine live (Medicare via NGSConnex). Commercial / WC / no-fault portals come later — those items are counted, not hidden from Craig."
                : "Run the full pipeline per patient, or sweep the whole queue."}
              {" "}Uncertain determinations fail closed to PENDING CRAIG — never guessed. Writes stay per-item + guarded.
              {d.cached && <span> · cached{d.stale ? " (stale)" : ""}{d.generatedAt ? " " + new Date(d.generatedAt).toLocaleTimeString() : ""}</span>}
            </div>
            <div style={{ display:"grid", gap:8, marginTop:10 }}>
              {!queue.length && (
                <div style={{ padding:"18px 14px", border:"1px dashed rgba(22,61,43,.20)", borderRadius:10, fontFamily:"var(--fs)", fontSize:13, color:"var(--ink-faint)" }}>
                  {isWorklist
                    ? (d.coverage && d.coverage.hidden>0 && !coverageAll
                        ? `No live-determinable (Medicare) items right now. ${d.coverage.hidden} item${d.coverage.hidden===1?"":"s"} in the bucket use payers without a live portal yet — tick "Show all payers" to see them.`
                        : "No pending-eligibility items in the bucket. Craig's queue is clear.")
                    : "No eligibility-required items for this day."}
                </div>
              )}
              {queue.map(row=>(
                <EligRow key={row.id} row={row} run={runs[row.id]} busy={busyId===row.id} onRun={onRun}
                  wb={wb[row.id]} onWriteback={onWriteback} busyWb={busyWbId===row.id}/>
              ))}
            </div>
          </div>

          <GoldsetCard goldset={d.goldset}/>
        </div>
      </div>
    );
  };
})();
