/* ═══════════════════════════════════════════════════════════
   OpAgent Inside — Admin Console (mirror of Provider console)
   Prep queue fed by the provider's "Send to Admin prep".
   Per patient: AuthCheck → Gap Analysis → PaQet + date picker.
   ═══════════════════════════════════════════════════════════ */

/* full admin workup — seed (Carlos) or live (cascade-driven bundle) */
function AdminWorkup({ pt, a, onStage, onGenerate, busyForm }){
  a = a || window.DEMO_ADMIN.rivera;
  const live = !!a.__live;
  const pickDays = a.paqet.pickDays || [];
  const [day, setDay] = useState(pickDays[0] ? pickDays[0].date : "");
  const [packet, setPacket] = useState(false);
  const gapItems = a.gap.items || [];
  const metCount = gapItems.filter(i=>i.met).length;
  const artifacts = a.paqet.artifacts || {};
  const anyArtifact = !!(artifacts.hpi || artifacts.consent || artifacts.booking);

  return (
    <div className="detail">

      {/* patient header */}
      <div className="pt-card">
        <div className="pt-head">
          <span className="cache" style={{background:"var(--forest-pale)",color:"var(--forest)"}}>IN PREP</span>
          <span className="pt-name">{(pt && pt.name) || a.procedure}</span>
          <span className="pill em">{a.code}</span>
          <span className="cached-at">sent by {a.sentBy} · {a.sentAt || (pt && pt.sentAt) || "today"}</span>
        </div>
        <div className="pt-body">
          <FRow label="Procedure"><span className="em-strong">{a.procedure}</span></FRow>
          <FRow label="Coverage"><b>{a.payer}</b></FRow>
          {live && a.noteExcerpt && <FRow label="Note">{a.noteExcerpt.slice(0,260)}{a.noteChars>260?" …":""}</FRow>}
        </div>
      </div>

      {/* AuthCheck */}
      <div className="step-card">
        <div className="step-head">
          <span className="eng codeiq">AUTHCHECK</span>
          <span className="step-title">Prior-authorization check</span>
          <span className="step-n">step 1</span>
        </div>
        <div className="step-body">
          <FRow label="Verdict">
            {a.authcheck.pending
              ? <span className="verdict-chip warn">running…</span>
              : <span className={"verdict-chip "+(a.authcheck.status==="clear"?"ok":"warn")}>{a.authcheck.status==="clear"?"✓ clear":"! attention"}</span>}
            <span style={{marginLeft:10}} className="em-strong">{a.authcheck.verdict}</span>
          </FRow>
          <FRow label="Detail">
            {a.authcheck.detail}
            {a.authcheck.source && <div className="authcheck-box" style={{marginTop:10}}>policy source <span className="src-tag">{a.authcheck.source}</span></div>}
          </FRow>
          {a.authcheck.basis && <FRow label="Basis">{a.authcheck.basis}</FRow>}
          {a.authcheck.requirements && a.authcheck.requirements.length>0 && (
            <FRow label="Payment gate"><ul className="gate-list">{a.authcheck.requirements.map((r,i)=><li key={i}>{r}</li>)}</ul></FRow>
          )}
          {a.authcheck.denialBenchmark && (
            <FRow label="Denial benchmark">
              <div className="bench"><b>{a.authcheck.denialBenchmark.n} denial(s) · {a.authcheck.denialBenchmark.atRisk} at risk</b> <span className="bench-src">— {a.authcheck.denialBenchmark.source}</span></div>
            </FRow>
          )}
        </div>
      </div>

      {/* Gap Analysis */}
      <div className="step-card">
        <div className="step-head">
          <span className="eng cliniq">GAP ANALYSIS</span>
          <span className="step-title">Against insurance policy</span>
          <span className="step-n">step 2</span>
        </div>
        <div className="step-body">
          <FRow label="Policy">{a.gap.policy}</FRow>
          <FRow label="Result">
            {a.gap.pending ? (
              <div className="gap-summary">Analyzing documentation gaps…</div>
            ) : live ? (
              <div className="gap-summary">
                {gapItems.length
                  ? <span><b>{gapItems.length}</b> documentation gap{gapItems.length===1?"":"s"} to close before booking</span>
                  : <span><b>No documentation gaps</b> detected for PA</span>}
              </div>
            ) : (
              <div className="gap-summary"><b>{metCount} of {gapItems.length}</b> requirements met · <span className="gap-verify">1 to verify before booking</span></div>
            )}
            <div className="gap-list">
              {gapItems.map((g,i)=>(
                <div key={i} className={"gap-row"+(g.met?" met":" miss")}>
                  <span className="gap-ic">{g.met?"✓":"!"}</span>
                  <div className="gap-main">
                    <div className="gap-req">{g.req}</div>
                    <div className="gap-found">{g.found}</div>
                  </div>
                </div>
              ))}
            </div>
          </FRow>
        </div>
      </div>

      {/* PaQet */}
      <div className="step-card">
        <div className="step-head">
          <span className="eng codeiq">PAQET</span>
          <span className="step-title">Generate surgical package</span>
          <span className="step-n">step 3</span>
        </div>
        <div className="step-body">
          <FRow label="Assembles">{a.paqet.intro}</FRow>
          <FRow label="Documents">
            <div className="doc-list">
              {a.paqet.docs.map((d,i)=>(
                <div key={i} className="doc-row">
                  <span className="doc-ic">{(live ? d.ready : packet) ? "✓" : "▤"}</span>
                  <span className="doc-name">{d.name}</span>
                  {d.auto && <span className="doc-auto">auto-drafted</span>}
                </div>
              ))}
            </div>
          </FRow>
          {live && anyArtifact && (
            <FRow label="Drafts">
              <div className="doc-list">
                {["hpi","consent","booking"].filter(k=>artifacts[k]).map(k=>(
                  <div key={k} className="note-preview" style={{marginTop:6}}><b>{k.toUpperCase()}</b> — {String(artifacts[k]).slice(0,360)}{String(artifacts[k]).length>360?" …":""}</div>
                ))}
              </div>
            </FRow>
          )}
          <FRow label="Book day">
            <div className="daypick">
              {pickDays.map((d,i)=>(
                <button key={i} className={day===d.date?"on":""} onClick={()=>setDay(d.date)}>
                  <div className="dw">{d.dow}</div><div className="dd">{d.date}</div>
                </button>
              ))}
            </div>
          </FRow>
          <div className="step-foot">
            {live ? (
              <>
                <button className="btn-confirm" disabled={busyForm==="hpi"} onClick={()=>onGenerate && onGenerate("hpi")}>{busyForm==="hpi"?"Generating…":(artifacts.hpi?"↻ HPI":"Generate HPI")}</button>
                <button className="btn-confirm" disabled={busyForm==="consent"} onClick={()=>onGenerate && onGenerate("consent")}>{busyForm==="consent"?"Generating…":(artifacts.consent?"↻ Consent":"Generate Consent")}</button>
                <button className="btn-confirm" disabled={busyForm==="booking"} onClick={()=>onGenerate && onGenerate("booking")}>{busyForm==="booking"?"Generating…":(artifacts.booking?"↻ Booking":"Booking form")}</button>
                <button className="btn-prep" onClick={()=>onStage({label:"Routed to scheduling"})}>Route to scheduling</button>
              </>
            ) : (
              <>
                <button className={"btn-confirm"+(packet?" done":"")} onClick={()=>{ if(!packet){ setPacket(true); onStage({label:"PaQet ready · 6 documents"}); } }}>
                  {packet ? "✓ Packet ready · 6 documents" : "Generate packet"}
                </button>
                <button className="btn-prep" onClick={()=>onStage({label:"Routed to scheduling"})}>Route to scheduling</button>
              </>
            )}
            <span className="day-stamp">book: {(pickDays.find(d=>d.date===day) && pickDays.find(d=>d.date===day).iso) || ("2026-"+day)}</span>
          </div>
        </div>
      </div>

    </div>
  );
}

function AdminConsole({ onStage, queue }){
  // Dispatch only — never call hooks here, so the live/seed branch can each own
  // their own hook order (window.DEMO.admin.__live is fixed for the session).
  return window.DEMO.admin.__live
    ? <AdminConsoleLive onStage={onStage}/>
    : <AdminConsoleSeed onStage={onStage} queue={queue||[]}/>;
}

function AdminConsoleLive({ onStage }){
  const A = window.DEMO.admin;
  const [prepByDate, setPrepByDate] = useState(A.__prepByDate || {});
  const [date, setDate] = useState(A.__date || window.Adapters.isoToday());
  const [rows, setRows] = useState([]);
  const [loading, setLoading] = useState(true);
  const [activeId, setActiveId] = useState(null);
  const [bundleMap, setBundleMap] = useState({}); // apptId -> { state, workup }
  const [busyForm, setBusyForm] = useState("");
  const pollRef = useRef(null);
  const seqRef = useRef(0);          // guards stale schedule responses
  const redirectedRef = useRef(false); // one-shot auto-hop to a day that has prep
  const dateOptions = Object.keys(prepByDate).filter(k=>prepByDate[k]>0).sort();

  // Load the tagged-prep queue for a date. The admin registry is keyed by the
  // office-visit scheduleDate, so a patient tagged from (say) Fri's schedule only
  // shows under that date — use the LIVE prepByDate from the response (not the
  // stale hydrate snapshot) and, if the chosen day is empty while another day has
  // prep, hop once to the most recent day that does. This is the fix for "the
  // Admin tab doesn't show the patient the provider just sent."
  function refreshQueue(targetDate){
    const dt = targetDate || date;
    const seq = ++seqRef.current;
    return window.Adapters.adminSchedule(dt).then(j=>{
      if(seq!==seqRef.current) return;
      const pbd = (j && j.prepByDate) || {};
      setPrepByDate(pbd);
      const sched = (j && j.schedule) || [];
      if(!sched.length && !redirectedRef.current){
        const withPrep = Object.keys(pbd).filter(k=>pbd[k]>0).sort();
        const newest = withPrep[withPrep.length-1];
        if(newest && newest!==dt){ redirectedRef.current = true; setDate(newest); return; }
      }
      const q = sched.map(r=>({
        id: r.appointmentId, name: r.patientName || "Patient", payer: r.payer || "",
        procedure: (r.procedureName||"procedure")+(r.cpt?" · "+r.cpt:""),
        sentBy: r.providerName || "provider", time: r.surgeryDay || r.scheduleDate,
      }));
      setRows(q);
      setLoading(false);
      setActiveId(prev=> (q.find(x=>x.id===prev) ? prev : (q.length ? q[0].id : null)));
    });
  }

  useEffect(()=>{ setLoading(true); refreshQueue(date); },[date]);

  // Catch a tag made while this tab was backgrounded (provider tags on the other
  // tab, then comes back) without a full remount — mirrors admin-chartq.js
  // pageshow/focus refresh.
  useEffect(()=>{
    const onShow = ()=>{ if(!document.hidden) refreshQueue(date); };
    window.addEventListener("focus", onShow);
    window.addEventListener("pageshow", onShow);
    document.addEventListener("visibilitychange", onShow);
    return ()=>{
      window.removeEventListener("focus", onShow);
      window.removeEventListener("pageshow", onShow);
      document.removeEventListener("visibilitychange", onShow);
    };
  },[date]);

  function loadBundle(apptId, showLoading){
    if(showLoading) setBundleMap(m=>({...m,[apptId]:{state:"loading"}}));
    window.Adapters.adminPatient(apptId).then(b=>{
      if(!b || b.error){ setBundleMap(m=>({...m,[apptId]:{state:"error", msg:(b&&b.error)||"bundle failed"}})); return; }
      setBundleMap(m=>({...m,[apptId]:{state:"ready", workup:window.Adapters.adaptAdminWorkup(b), raw:b}}));
    });
  }
  // Load + poll the active patient bundle (catches background engine + paqet updates).
  useEffect(()=>{
    if(!activeId) return;
    loadBundle(activeId, true);
    if(pollRef.current) clearInterval(pollRef.current);
    pollRef.current = setInterval(()=>loadBundle(activeId, false), 3000);
    return ()=>{ if(pollRef.current){ clearInterval(pollRef.current); pollRef.current=null; } };
  },[activeId]);

  async function genPaqet(form){
    if(!activeId) return;
    setBusyForm(form);
    onStage({label:"Generating "+form+"…"});
    const res = await window.Adapters.adminPaqet(activeId, form);
    setBusyForm("");
    if(res && !res.error){ onStage({label:form.toUpperCase()+" generated"}); loadBundle(activeId, false); }
    else onStage({label:"PaQet failed — "+((res&&res.error)||"retry")});
  }

  if(!rows.length){
    return (
      <div className="screen">
        <div className="phys2-bar">
          <span className="phys2-status" style={{marginLeft:0}}><b style={{color:"var(--forest)",fontFamily:"var(--fb)",fontWeight:600}}>Prep queue</b> · live from the cockpit</span>
          {dateOptions.length>0 && <span className="phys2-status">{dateOptions.map(d=>(<button key={d} className={"phys2-load"+(d===date?" on":"")} style={{marginLeft:6}} onClick={()=>{redirectedRef.current=true; setDate(d);}}>{d} ({prepByDate[d]})</button>))}</span>}
        </div>
        <div className="awaiting" style={{marginTop:8}}>
          <div className="aw-scope"><ScopeIc size={44}/></div>
          {loading
            ? <><h3>Loading prep queue…</h3><p>Reading the tagged-prep registry for {date}.</p></>
            : <><h3>No patients tagged for {date}</h3>
                <p>Providers send patients here from the schedule with <b>"Send to Admin prep."</b> When they do, the patient lands in this queue and OpAgent runs AuthCheck, Gap Analysis and PaQet against the payer policy.{dateOptions.length>0 ? " Other days have prep queued — switch dates above." : ""}</p></>}
        </div>
      </div>
    );
  }

  const active = rows.find(r=>r.id===activeId) || rows[0];
  const b = bundleMap[activeId];

  return (
    <div className="screen">
      <div className="phys2-bar">
        <span className="phys2-status" style={{marginLeft:0}}>
          <b style={{color:"var(--forest)",fontFamily:"var(--fb)",fontWeight:600}}>Prep queue</b> · {rows.length} patient{rows.length>1?"s":""} · office {date}
        </span>
        {dateOptions.length>1 && <span className="phys2-status">{dateOptions.map(d=>(<button key={d} className={"phys2-load"+(d===date?" on":"")} style={{marginLeft:6}} onClick={()=>{redirectedRef.current=true; setDate(d);}}>{d} ({prepByDate[d]})</button>))}</span>}
        <span className="phys2-status">AuthCheck · Gap Analysis · PaQet</span>
      </div>

      <div className="phys2-grid">
        <div className="rail">
          <div className="rail-day">
            <h3>Prep queue</h3>
            <span className="rd-sub">{rows.length} tagged · office {date}</span>
          </div>
          <div className="rail-list" style={{borderTop:"1px solid var(--canvas-mid)"}}>
            {rows.map(s=>(
              <button key={s.id} className={"rail-row"+(active && active.id===s.id?" on":"")} style={{"--accent":"#C4973E"}} onClick={()=>setActiveId(s.id)}>
                <div className="rr-top">
                  <span className="rr-time">{s.time}</span>
                  <span className="rr-name">{s.name}</span>
                  <span className="rr-dot planned"></span>
                </div>
                <span className="rr-payer">{s.payer}</span>
                <div className="rr-comp">{s.procedure} · sent by {s.sentBy}</div>
              </button>
            ))}
          </div>
        </div>

        {(!b || b.state==="loading")
          ? <div className="detail"><div className="awaiting"><div className="aw-scope"><ScopeIc size={44}/></div><h3>Loading prep bundle — <span className="aw-name">{active.name}</span></h3><p>Running AuthCheck and the AdminQ gap analyzer against {active.payer}. First run takes a moment; cached patients open instantly.</p></div></div>
          : b.state==="error"
            ? <div className="detail"><div className="awaiting"><div className="aw-scope"><ScopeIc size={44}/></div><h3>Couldn't load prep — <span className="aw-name">{active.name}</span></h3><p>{b.msg}</p><button className="aw-run" onClick={()=>loadBundle(activeId,true)}>Retry →</button></div></div>
            : <AdminWorkup pt={active} a={b.workup} onStage={onStage} onGenerate={genPaqet} busyForm={busyForm}/>}
      </div>
    </div>
  );
}

/* ── seed-mode prep queue (offline fallback, provider-sent local list) ── */
function AdminConsoleSeed({ onStage, queue }){
  const [activeId, setActiveId] = useState(queue.length ? queue[0].id : null);
  const active = queue.find(q=>q.id===activeId) || queue[0];

  if(!queue.length){
    return (
      <div className="screen">
        <div className="awaiting" style={{marginTop:8}}>
          <div className="aw-scope"><ScopeIc size={44}/></div>
          <h3>No patients in prep yet</h3>
          <p>Providers send patients here from the schedule with <b>"Send to Admin prep."</b> When they do, the patient lands in this queue and OpAgent runs AuthCheck, Gap Analysis and PaQet against the payer policy.</p>
        </div>
      </div>
    );
  }

  return (
    <div className="screen">
      <div className="phys2-bar">
        <span className="phys2-status" style={{marginLeft:0}}>
          <b style={{color:"var(--forest)",fontFamily:"var(--fb)",fontWeight:600}}>Prep queue</b> · {queue.length} patient{queue.length>1?"s":""} sent by provider
        </span>
        <span className="phys2-status">AuthCheck · Gap Analysis · PaQet</span>
      </div>

      <div className="phys2-grid">
        <div className="rail">
          <div className="rail-day">
            <h3>Prep queue</h3>
            <span className="rd-sub">{queue.length} sent · {queue.length} ready</span>
          </div>
          <div className="rail-list" style={{borderTop:"1px solid var(--canvas-mid)"}}>
            {queue.map(s=>(
              <button key={s.id} className={"rail-row"+(active && active.id===s.id?" on":"")} style={{"--accent":"#C4973E"}} onClick={()=>setActiveId(s.id)}>
                <div className="rr-top">
                  <span className="rr-time">{s.sentAt||s.time}</span>
                  <span className="rr-name">{s.name}</span>
                  <span className="rr-dot planned"></span>
                </div>
                <span className="rr-payer">{s.payer}</span>
                <div className="rr-comp">{s.procedure} · sent by {s.sentBy||"provider"}</div>
              </button>
            ))}
          </div>
        </div>

        {active && active.id==="rivera"
          ? <AdminWorkup pt={active} onStage={onStage}/>
          : <div className="detail"><div className="awaiting"><div className="aw-scope"><ScopeIc size={44}/></div><h3>Awaiting prep — <span className="aw-name">{active.name}</span></h3><p>Run AuthCheck, Gap Analysis and PaQet against {active.payer}.</p><button className="aw-run" onClick={()=>onStage({label:"Running prep for "+active.name})}>Run prep →</button></div></div>}
      </div>
    </div>
  );
}

/* ── module wrapper with Console / Cards toggle ── */
function AdminModule({ onStage, queue }){
  const [view, setView] = useState("console");
  return (
    <div className="screen">
      <div className="mod-intro">
        <div><h2>Admin</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" ? <AdminConsole onStage={onStage} queue={queue||[]}/> : <AdminCards onStage={onStage}/>}
    </div>
  );
}

Object.assign(window, { AdminConsole, AdminModule });
