/* ═══════════════════════════════════════════════════════════
   OpAgent Inside — neu-RCM (the owner's money board)
   Unsubmitted (Prevent) · Submitted (Recover) · ROI Ledger
   ═══════════════════════════════════════════════════════════ */

/* engine → action-pill signature color class (rim + text). Keyed to engine so
   the same engine always reads the same color across the worklist. Falls back
   to the neutral .action-pill rim for unmapped engines. */
const PILL_ENGINE = {
  AppealQ:     "pill--appealq",
  DeniQ:       "pill--deniq",
  CodeIQ:      "pill--codeiq",
  Eligibility: "pill--eligibility",
  DataQorp:    "pill--dataqorp"
};
function enginePillClass(engine){
  return "action-pill " + (PILL_ENGINE[engine] || "");
}

/* who/what caught it */
function SourceTag({ source }){
  const map = {
    intake:        { label:"intake sweep",   cls:"src-intake" },
    physician_dos: { label:"provider @ DOS",  cls:"src-dos" },
    admin:         { label:"admin prep",      cls:"src-admin" },
    agent_sweep:   { label:"agent sweep",     cls:"src-agent" }
  };
  const s = map[source] || { label:source, cls:"" };
  return <span className={"source-tag "+s.cls}>{source==="agent_sweep" && "◆ "}{s.label}</span>;
}

function PnlStrip({ pnl, attributed, onRoi }){
  return (
    <div className="pnl pnl5">
      <div className="pnl-cell">
        <div className="pl">Cash posted</div>
        <div className="pv gilt">{pnl.cashPosted.value}</div>
        <div className="ps"><span className="up">{pnl.cashPosted.up}</span> · {pnl.cashPosted.sub}</div>
      </div>
      <div className="pnl-cell">
        <div className="pl">Ready to bill</div>
        <div className="pv">{pnl.readyToBill.value}</div>
        <div className="ps">{pnl.readyToBill.sub}</div>
      </div>
      <div className="pnl-cell">
        <div className="pl">A/R by age</div>
        <div className="agebars">
          {pnl.arAge.buckets.map((b,i)=>(
            <div key={i} className={"ab"+(b.old?" old":"")} style={{height:b.h+"%"}}><span className="abl">{b.label}</span></div>
          ))}
        </div>
        <div className="ps" style={{marginTop:22}}>{pnl.arAge.sub}</div>
      </div>
      <div className="pnl-cell">
        <div className="pl">Recovered vs lost</div>
        <div className="pv">{pnl.recoveredVsLost.recovered} <span style={{fontSize:18,color:"#E8B98C",fontWeight:400}}>/ {pnl.recoveredVsLost.lost}</span></div>
        <div className="ps">{pnl.recoveredVsLost.sub}</div>
      </div>
      <button className="pnl-cell attr" onClick={onRoi}>
        <div className="pl">OpAgent-attributed $</div>
        <div className="pv gilt">{attributed.value}</div>
        <div className="ps">{attributed.sub} · <span className="up">{attributed.roiHint} ↗</span></div>
      </button>
    </div>
  );
}

/* ── PREVENT row (release / fix) ── */
function PreventRow({ r, onStage }){
  return (
    <div className="prow">
      <div className="prow-main">
        <div className="prow-play" dangerouslySetInnerHTML={{__html:r.play}}/>
        {r.detail && <div className="prow-detail">{r.detail}</div>}
        <div className="prow-meta">
          <CptChip code={r.cpt}/>
          <PayerChip name={r.payer}/>
          <EngineChip name={r.engine}/>
          <OwnerChip name={r.owner}/>
          <SourceTag source={r.source}/>
          <span className="claimid">{r.claimId}</span>
        </div>
      </div>
      <div className="prow-side">
        {r.amount && <Dollar amount={r.amount} sm/>}
        <ClockChip when={r.clock} urgent={r.urgent}/>
        <DeepLink onStage={()=>onStage(r)}/>
      </div>
    </div>
  );
}

function YieldTrend({ trend }){
  const pts = trend.points;
  const W=560, H=150, padL=8, padR=44, padT=14, padB=26;
  const min=86, max=97;
  const x = i => padL + i*((W-padL-padR)/(pts.length-1));
  const y = v => padT + (1-(v-min)/(max-min))*(H-padT-padB);
  const line = pts.map((p,i)=>`${x(i).toFixed(1)},${y(p.v).toFixed(1)}`).join(" ");
  const area = `${padL},${(H-padB).toFixed(1)} ${line} ${(W-padR).toFixed(1)},${(H-padB).toFixed(1)}`;
  const last = pts[pts.length-1];
  return (
    <div className="card yield-card">
      <div className="yield-head">
        <div>
          <div className="yield-title">First-pass clean-claim yield</div>
          <div className="yield-sub">{trend.sub}</div>
        </div>
        <div className="yield-now"><span className="yn-v">{last.v}%</span><span className="yn-l">this month</span></div>
      </div>
      <div className="yield-plot">
        <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" style={{width:"100%",height:150}}>
          <polygon points={area} fill="rgba(45,122,84,0.10)"/>
          <polyline points={line} fill="none" stroke="#2D7A54" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
          {pts.map((p,i)=>(
            <g key={i}>
              <circle cx={x(i)} cy={y(p.v)} r={i===pts.length-1?4.5:3} fill={i===pts.length-1?"#C4973E":"#2D7A54"}/>
              <text x={x(i)} y={H-10} textAnchor="middle" fontFamily="'IBM Plex Mono',monospace" fontSize="9" fill="#9C988D">{p.m}</text>
            </g>
          ))}
        </svg>
      </div>
      <div className="yield-callout"><span className="yc-ic">◆</span> {trend.callout}</div>
    </div>
  );
}

function PreventView({ p, onStage }){
  return (
    <div className="screen">
      {/* intake sweep banner */}
      <div className="intake">
        <div className="intake-l">
          <div className="intake-tag">Intake sweep · on connect</div>
          <div className="intake-line">
            <b>{p.intakeSweep.reviewed}</b> pending claims reviewed · <span className="ok">{p.intakeSweep.clean} clean to release</span> · <span className="warn">{p.intakeSweep.needFix} need a fix before they'd bounce</span>
          </div>
          <div className="intake-note">{p.intakeSweep.note}</div>
        </div>
      </div>

      <div className="prevent-cols">
        <div className="pcol">
          <div className="pcol-head release">
            <span className="pcol-title">Release</span>
            <span className="pcol-sub">clean · just sitting · losing the filing clock</span>
            <span className="pcol-n">{p.release.length}</span>
          </div>
          {p.release.map((r,i)=><PreventRow key={i} r={r} onStage={onStage}/>)}
        </div>
        <div className="pcol">
          <div className="pcol-head fix">
            <span className="pcol-title">Fix before send</span>
            <span className="pcol-sub">scrub before it goes out</span>
            <span className="pcol-n">{p.fix.length}</span>
          </div>
          {p.fix.map((r,i)=><PreventRow key={i} r={r} onStage={onStage}/>)}
        </div>
      </div>

      {/* safety-net */}
      <SHead title="Safety-net" count="about to submit with a flagged issue · tagged by who caught it"/>
      <div className="card" style={{padding:"4px 0"}}>
        {p.safetyNet.map((s,i)=>(
          <div key={i} className={"snet"+(s.source==="agent_sweep"?" agent":"")}>
            <div className="snet-l">
              <SourceTag source={s.source}/>
              <div>
                <div className="snet-flag">{s.flag}</div>
                <div className="snet-note">{s.note} <span className="claimid">{s.claimId}</span></div>
              </div>
            </div>
            <Dollar amount={s.amount} sm/>
          </div>
        ))}
      </div>

      {/* yield trend */}
      <SHead title="Clean-claim yield" count="proof it's working"/>
      <YieldTrend trend={p.yieldTrend}/>
    </div>
  );
}

/* ── AppealQ inline experience (Draft → Drafted → edit → PDF/Doc → gated push) ──
   The "Draft appeal" pill calls the backend, which GENERATES + STORES a real,
   payer-specific letter (Bedrock, claim-keyed). The pill flips to "Drafted", an
   inline editable panel expands under the card, PDF/Doc download buttons appear,
   and "Push to DrChrono" is gated by INSIDE_ARM_WRITES — OFF for the demo, so it
   STAGES (no EMR write). State re-hydrates from the store on render. */
function AppealExperience({ claimId, onStage }){
  const [ap, setAp]       = useState(null);   // stored appeal record (null until drafted)
  const [open, setOpen]   = useState(false);
  const [letter, setLetter] = useState("");
  const [busy, setBusy]   = useState("");     // "", "draft", "save", "push"

  // Re-hydrate the Drafted state + stored letter when the card renders.
  useEffect(()=>{
    let on = true;
    if(claimId){
      window.Adapters.appealGet(claimId).then(r=>{
        if(on && r && r.letter){ setAp(r); setLetter(r.letter); }
      });
    }
    return ()=>{ on = false; };
  },[claimId]);

  async function doDraft(){
    if(busy) return;
    setBusy("draft");
    onStage && onStage({label:"AppealQ is drafting a payer-specific appeal letter…"});
    const r = await window.Adapters.appealDraft(claimId);
    setBusy("");
    if(r && r.letter){
      setAp(r); setLetter(r.letter); setOpen(true);
      onStage && onStage({label:"AppealQ drafted the appeal — review & edit before download"});
    } else {
      onStage && onStage({label:"Couldn't draft the appeal — check the live connection"});
    }
  }
  async function doSave(){
    if(busy) return;
    setBusy("save");
    const r = await window.Adapters.appealSave(claimId, letter);
    setBusy("");
    if(r){ setAp(r); onStage && onStage({label:"Appeal edits saved"}); }
  }
  async function doPush(){
    if(busy) return;
    setBusy("push");
    const r = await window.Adapters.appealPush(claimId);
    setBusy("");
    if(r){
      setAp(r);
      onStage && onStage({label: r.armed
        ? "Pushed appeal to DrChrono"
        : "Staged — arm writes to push to DrChrono (no EMR write performed)"});
    }
  }

  const staged = ap && ap.push && ap.push.staged;
  return (
    <>
      <div className="cl-actions">
        {!ap
          ? <button className={enginePillClass("AppealQ")} disabled={busy==="draft"} onClick={doDraft}>
              {busy==="draft" ? "Drafting…" : "Draft appeal"}
            </button>
          : <div className="appeal-controls">
              <button className="appeal-drafted" onClick={()=>setOpen(o=>!o)}>
                <span className="ad-ic">✓</span> Drafted <span className="ad-car">{open?"▾":"▸"}</span>
              </button>
              <a className="action-pill pill--dl" href={window.Adapters.appealPdfUrl(claimId)} target="_blank" rel="noopener noreferrer">PDF</a>
              <a className="action-pill pill--dl" href={window.Adapters.appealDocUrl(claimId)} target="_blank" rel="noopener noreferrer">Doc</a>
            </div>}
        <DeepLink label="Deep-link to DrChrono" onStage={()=>onStage({label:"Opening claim "+claimId+" in DrChrono"})}/>
      </div>
      {ap && open && (
        <div className="appeal-panel">
          <div className="appeal-panel-head">
            <span className="ap-title">Appeal letter — claim {claimId}</span>
            <span className="ap-meta">
              {ap.generator==="bedrock" ? "drafted by OpAgent (Bedrock)" : "drafted from claim data (template)"}
              {ap.noteCited ? " · note evidence cited" : " · no note excerpt available"}
            </span>
          </div>
          <textarea className="appeal-textarea" value={letter} onChange={e=>setLetter(e.target.value)} spellCheck={false}/>
          <div className="appeal-panel-foot">
            <button className="action-pill" disabled={busy==="save"} onClick={doSave}>{busy==="save"?"Saving…":"Save edits"}</button>
            <button className={"action-pill pill--push"+(staged?" is-staged":"")} disabled={busy==="push"} onClick={doPush}>
              {busy==="push" ? "Pushing…" : staged ? "Staged — writes off" : "Push to DrChrono"}
            </button>
            <span className="appeal-note">
              {staged
                ? "Staged for chart attach · arm writes to push — proposes, never writes"
                : "Generates & stores the letter · proposes, never writes to the EMR"}
            </span>
          </div>
        </div>
      )}
    </>
  );
}

/* ── RECOVER (submitted) ── */
function Cluster({ c, variant, onStage }){
  const chartNum = c.chartId || c.mrn;
  const canAppeal = !!(c.draftAppeal && c.claimId);
  return (
    <div className={"cluster "+variant}>
      <div className="cluster-top">
        <div style={{minWidth:0}}>
          <div className="carc">{c.carc}{c.overturn && <span style={{color:"var(--gilt-dark)",fontWeight:600}}> · {c.overturn}</span>}</div>
          <div className="cl-title" dangerouslySetInnerHTML={{__html:c.title}}/>
          {c.pat && (
            <div className="cl-id">
              <span className="cl-id-name">{c.pat}</span>
              {chartNum && <><span className="cl-id-sep">·</span><span>Chart #{chartNum}</span></>}
              {c.payer && <><span className="cl-id-sep">·</span><span>{c.payer}</span></>}
            </div>
          )}
          <div className="cl-fix" dangerouslySetInnerHTML={{__html:c.fix}}/>
        </div>
        <div className="cl-side">
          <Dollar amount={c.dollar} refTag={c.ref}/>
          <div className="cl-n">{c.n}</div>
        </div>
      </div>
      <div className="cluster-foot">
        <EngineChip name={c.engine}/>
        <OwnerChip name={c.owner}/>
        {c.note && <Chip kind="sev-rej">{c.note}</Chip>}
        {canAppeal
          ? <AppealExperience claimId={c.claimId} onStage={onStage}/>
          : (
            <div className="cl-actions">
              {c.draftAppeal && <button className={enginePillClass("AppealQ")} onClick={()=>onStage({label:"AppealQ drafted an appeal"})}>Draft appeal</button>}
              <DeepLink label="Deep-link to DrChrono" onStage={()=>onStage(c)}/>
            </div>
          )}
      </div>
    </div>
  );
}

function RecoverView({ r, onStage }){
  return (
    <div className="screen">
      <SHead title="Rejections to rework" count="999 / 277CA · front-end · never adjudicated — not denials"/>
      {r.rejections.map((c,i)=><Cluster key={i} c={c} variant="" onStage={onStage}/>)}

      <SHead title="Denials to appeal" count="ranked by CARC × overturn-prior × dollars"/>
      {r.denials.map((c,i)=><Cluster key={i} c={c} variant="denial" onStage={onStage}/>)}

      <SHead title="Underpayments to recoup" count="paid below expected · Medicare PFS benchmark"/>
      {r.underpayments.map((c,i)=><Cluster key={i} c={c} variant="under" onStage={onStage}/>)}

      <SHead title="A/R to chase" count="oldest-and-largest first"/>
      {r.ar.map((c,i)=><Cluster key={i} c={c} variant="ar" onStage={onStage}/>)}
    </div>
  );
}

/* ── Learned → Prevented loop ── */
function LearnedPanel({ learned }){
  return (
    <div className="learned">
      <div className="learned-head">
        <h3>Learned → <em>now prevented</em></h3>
        <span className="lh-tag">the loop</span>
      </div>
      <div className="learned-sub">What your <b>submitted</b> claims failed on becomes the rule guarding your <b>unsubmitted</b> claims. This is what makes the board preventive — not just a recovery list.</div>
      <div className="learned-grid">
        {learned.map((l,i)=>(
          <div key={i} className="lrow">
            <div className="lr-was">
              <div className="lr-pat">{l.pat}</div>
              <div className="lr-cost">{l.cost}</div>
            </div>
            <div className="lr-arrow">→</div>
            <div className="lr-now">
              <span className="lr-shield">✓</span>
              <span className="lr-rule">{l.rule}<span className="eng">{l.engine} · now guarding</span></span>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

/* ── ROI Ledger ── */
function OutcomeChip({ outcome }){
  const map = {
    realized:       { label:"realized",        cls:"oc-realized" },
    open:           { label:"open",            cls:"oc-open" },
    acted_other:    { label:"acted (other)",   cls:"oc-other" },
    not_acted:      { label:"not acted",       cls:"oc-not" },
    unattributable: { label:"unattributable",  cls:"oc-un" }
  };
  const o = map[outcome] || { label:outcome, cls:"" };
  return <span className={"oc "+o.cls}>{o.label}</span>;
}

function RoiLedger({ roi, onStage }){
  return (
    <div className="screen">
      <div className="roi-headline">
        <div className="roi-total">
          <div className="rt-l">OpAgent-attributed dollars · this period</div>
          <div className="rt-v">{roi.attributedTotal}</div>
        </div>
        <div className="roi-split">
          <div className="rs-cell">
            <div className="rs-l">{roi.recovered.label}</div>
            <div className="rs-v">{roi.recovered.value}</div>
            <div className="rs-s">{roi.recovered.sub}</div>
          </div>
          <div className="rs-cell">
            <div className="rs-l">{roi.prevented.label}</div>
            <div className="rs-v gilt">{roi.prevented.value}</div>
            <div className="rs-s">{roi.prevented.sub}</div>
          </div>
        </div>
      </div>

      <SHead title="Attribution ledger" count="every recommendation → claim · projected → realized · acted-by · outcome"/>
      <div className="card roi-table-wrap">
        <table className="roi-table">
          <thead>
            <tr>
              <th>Rec / Claim</th><th>Play</th><th className="num">Projected</th><th className="num">Realized</th>
              <th>Acted by</th><th>Outcome</th><th>Conf.</th><th></th>
            </tr>
          </thead>
          <tbody>
            {roi.rows.map((r,i)=>(
              <tr key={i}>
                <td><span className="rec-id">{r.recId}</span><span className="claimid">{r.claimId}</span></td>
                <td className="roi-play">{r.play}{r.prevented && <span className="prev-tag">prevented</span>}</td>
                <td className="num mono">{r.projected}{r.ref && <span className="ref">REF</span>}</td>
                <td className="num mono realized">{r.realized}</td>
                <td><span className="acted">{r.actedBy}</span><SourceTag source={r.source}/></td>
                <td><OutcomeChip outcome={r.outcome}/></td>
                <td><span className={"conf conf-"+r.confidence}>{r.confidence}</span></td>
                <td><button className="roi-link" onClick={()=>onStage({label:"Opening "+r.claimId+" in DrChrono"})}>↗</button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <div className="roi-subtotal">
        <div className="rsub-l">Billable subtotal <span className="rsub-note">high-confidence · attributed · recovered only — never coding-uplift, never counterfactual prevention</span></div>
        <div className="rsub-v">{roi.billableSubtotal}</div>
      </div>

      <div className="foot-note">
        OpAgent proposes; your team commits. <b>Every dollar traces to a claim.</b> <Ref/> = reference figure (Medicare PFS, overturn priors), never your contracted rate. Prevented value is estimated and <b>not billed</b>.
      </div>
    </div>
  );
}

function AnalyticsBlock({ a }){
  const ref = useRef(null);
  useEffect(()=>{
    const el = ref.current; if(!el) return;
    requestAnimationFrame(()=>{ el.querySelectorAll(".an-fill").forEach(f=>{ f.style.width = f.dataset.w+"%"; }); });
  },[]);
  function col(title, tag, rows){
    return (
      <div className="an-card">
        <div className="an-h"><div className="an-title">{title}</div><div className="an-tag">{tag}</div></div>
        {rows.map((row,i)=>(
          <div key={i} className="an-row">
            <div className="an-lab">{row.lab}</div>
            <div className="an-track"><div className={"an-fill"+(row.gilt?" gilt":"")} data-w={row.pct}></div></div>
            <div className="an-val">{row.val}</div>
          </div>
        ))}
      </div>
    );
  }
  return (
    <div ref={ref}>
      <SHead title="Analytics" count="by insurance · procedure · provider"/>
      <div className="analytics">
        {col("By insurance","share of revenue", a.byInsurance)}
        {col("By procedure","real revenue CPTs only", a.byProcedure)}
        {col("By provider","collections MTD", a.byProvider)}
      </div>
      <div className="foot-note" style={{marginTop:18}}>
        Procedure view filters to real revenue CPTs — <b>excludes J-codes, PHONE, and quality codes</b>. Benchmarks shown <Ref/> are reference-derived, never sold as the practice's contracted rate.
      </div>
    </div>
  );
}

function NeuRcmModule({ onStage }){
  const N = window.DEMO.neurcm;
  const [view, setView] = useState("prevent"); // prevent | recover | roi

  return (
    <div className="screen">
      <div className="mod-intro">
        <div><h2>neu-RCM</h2></div>
      </div>

      <PnlStrip pnl={N.pnl} attributed={N.attributed} onRoi={()=>setView("roi")}/>

      <div style={{display:"flex",justifyContent:"center",margin:"26px 0 18px"}}>
        <div className="seg seg3">
          <button className={view==="prevent"?"on":""} onClick={()=>setView("prevent")}><span className="sgi">⤧</span> Unsubmitted · Prevent</button>
          <button className={view==="recover"?"on":""} onClick={()=>setView("recover")}><span className="sgi">↺</span> Submitted · Recover</button>
          <button className={view==="roi"?"on":""} onClick={()=>setView("roi")}><span className="sgi">∑</span> ROI Ledger</button>
        </div>
      </div>

      {view==="prevent" && <><PreventView p={N.prevent} onStage={onStage}/><LearnedPanel learned={N.learned}/><AnalyticsBlock a={N.analytics}/></>}
      {view==="recover" && <><RecoverView r={N.retro} onStage={onStage}/><LearnedPanel learned={N.learned}/><AnalyticsBlock a={N.analytics}/></>}
      {view==="roi" && <RoiLedger roi={N.roi} onStage={onStage}/>}

      {view!=="roi" && (
        <div className="foot-note">
          <b>Rejections ≠ denials.</b> 999/277CA front-end rejections never reached adjudication — reworked &amp; resubmitted, never appealed. Denials are ranked by CARC × overturn-prior × dollars. OpAgent stages; a human commits — nothing auto-submits or auto-appeals.
        </div>
      )}
    </div>
  );
}

Object.assign(window, { NeuRcmModule });
