/* refill.jsx — Refill department (intake): refill gaps + the on-hold backlog.
   Full filter rail; backlog KPI cards respect payer/line/brand via dims. */
const { D, fmt, pct, fmtMonthLong } = window.RX;

const GAP_COLS = [
  ["patient", "Patient", false], ["drug", "Drug", false], ["days_overdue", "Days overdue", true],
  ["last_fill", "Last fill", false], ["refill_due", "Refill due", false], ["payer", "Insurance", false],
];

function dimSum(rows, payerNames, lines, fams, bandIdx) {
  // rows: [payer, line, family, (band), count]
  let s = 0;
  const out = {};
  for (const r of rows || []) {
    const [payer, line, family] = r;
    const n = r[r.length - 1];
    if (payerNames && !payerNames.has(String(payer).toUpperCase())) continue;
    if (lines && D.lines.includes(line) && !lines.has(line)) continue;
    if (fams && !fams.has(String(family).toUpperCase())) continue;
    s += n;
    if (bandIdx != null) out[r[bandIdx]] = (out[r[bandIdx]] || 0) + n;
  }
  return bandIdx != null ? out : s;
}

function Refill({ filter }) {
  const payerNames = filter.payers.size === D.payers.length ? null
    : new Set([...filter.payers].map(i => D.payers[i].name.toUpperCase()));
  const allProducts = filter.products.size === D.drugs.length;
  const fams = allProducts ? null : new Set([...filter.products].map(i => (D.drugs[i].family || "Other").toUpperCase()));
  const lines = filter.lines.size === D.lines.length ? null : filter.lines;
  const anyFilter = payerNames || fams || lines;

  // ---- refill gaps (row-wise filtering) ----
  const [sort, setSort] = useState({ key: "days_overdue", desc: true });
  const gaps = (D.refill_gaps || [])
    .filter(g => (!payerNames || payerNames.has(String(g.payer).toUpperCase()))
      && (!lines || !D.lines.includes(g.line) || lines.has(g.line))
      && (!fams || fams.has(String(g.family).toUpperCase())))
    .sort((a, b) => {
      const k = sort.key, va = a[k], vb = b[k];
      const c = typeof va === "number" ? va - vb : String(va).localeCompare(String(vb));
      return sort.desc ? -c : c;
    });
  const shownGaps = gaps.slice(0, 100);

  // ---- backlog: narrowed to Staged only (Total/Dummy/Parked + parked-aging
  // histogram dropped per the owner). Staged respects the rail via dim.staged. ----
  const bk = D.backlog, dim = D.backlog_dim;
  const staged = dim ? dimSum(dim.staged, payerNames, lines, fams) : null;
  // Work list carries script-number-only fields, so it filters by service line
  // (the dimension it exposes); payer/product filtering applies to the staged KPI.
  const due = (bk && bk.staged_due || [])
    .filter(r => (!lines || !D.lines.includes(r.service_line) || lines.has(r.service_line)))
    .slice(0, 100);
  const [copied, setCopied] = useState(false);
  const copy = () => {
    navigator.clipboard && navigator.clipboard.writeText(due.map(r => r.script_number).join("\n"));
    setCopied(true); setTimeout(() => setCopied(false), 1600);
  };
  const scope = anyFilter ? "filtered payers/products" : "all payers · all products";

  const arrow = (k) => sort.key === k ? (sort.desc ? " ▼" : " ▲") : "";
  const clickSort = (k, num) => setSort(s => s.key === k ? { key: k, desc: !s.desc } : { key: k, desc: !!num });

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1>Refill</h1>
          <p>The refill department's intake: patient + drug combinations overdue for a fill, and everything currently flagged On Hold in Liberty split into what it actually is.</p>
        </div>
        <div className="lens-flag">As of <b>{window.RX.fmtDateY(D.as_of)}</b></div>
      </div>

      <Card title="Refill gaps" desc="Patient + drug combinations where the Refill Due date has passed and no subsequent fill has arrived. Snapshot as of the most recent refresh."
        meta={`${fmt(shownGaps.length)} of ${fmt(D.refill_gaps_total ?? gaps.length)} overdue · ${scope}`} style={{ marginBottom: "var(--gap)" }}>
        {D.refill_gaps && D.refill_gaps.length ? (
          <div className="matrix-wrap" style={{ maxHeight: 420, border: "1px solid var(--border)" }}>
            <table>
              <thead><tr>{GAP_COLS.map(([k, lab, num]) =>
                <th key={k} className={num ? "num" : ""} style={{ cursor: "pointer" }} onClick={() => clickSort(k, num)}>{lab}{arrow(k)}</th>)}
              </tr></thead>
              <tbody>
                {shownGaps.map((g, i) => (
                  <tr key={i}>
                    <td className="mono">{g.patient}</td>
                    <td style={{ color: "var(--text-2)" }} title={g.drug}>{g.drug.length > 30 ? g.drug.slice(0, 30) + "…" : g.drug}</td>
                    <td className="num"><span className={g.days_overdue > 60 ? "tag" : g.days_overdue > 30 ? "tag warn" : "tag pos"}>{g.days_overdue}</span></td>
                    <td className="mono">{g.last_fill}</td>
                    <td className="mono">{g.refill_due}</td>
                    <td>{g.payer}</td>
                  </tr>))}
              </tbody>
            </table>
          </div>
        ) : <div className="empty">No refill gaps detected.</div>}
        <div className="note">Click a column header to re-sort. Patient handles are de-identified hashes — no names or DOBs.</div>
      </Card>

      <Card title="On-hold backlog — staged next-cycle Rx"
        desc="Real prescriptions currently on hold, staged for on-service patients: the next-cycle replacement of a previous fill, parked on the profile until the patient's due date (healthy by design — not a review pile)."
        meta={bk ? `${fmt(staged != null ? staged : bk.real_staged)} staged · ${scope}` : "as-of snapshot"}>
        {bk ? (<>
          <div className="grid" style={{ gridTemplateColumns: "minmax(220px,360px)", marginBottom: "var(--gap)" }}>
            <KPI feature label="Staged next-cycle Rx" value={staged != null ? fmt(staged) : fmt(bk.real_staged)} accentBar="var(--pos)"
              sub={bk.real_staged_due_now ? `${fmt(bk.real_staged_due_now)} now due to fill` : "waiting on due dates · healthy by design"} />
          </div>

          <Card title="Staged & due now — fillable work list"
            desc="Staged e-scripts whose patient's supply coverage has lapsed — ready to fill. Freshest lapse first; script numbers only, no patient identifiers."
            right={<button className="pillbtn" onClick={copy}><Ico size={13} d={copied ? ICONS.check : ICONS.copy} />{copied ? "Copied" : `Copy script numbers (${due.length})`}</button>}>
            <div className="matrix-wrap" style={{ maxHeight: 360, border: "1px solid var(--border)" }}>
              <table>
                <thead><tr><th>Script Number</th><th>Service line</th><th>Queue</th><th className="num">Days since coverage lapsed</th></tr></thead>
                <tbody>
                  {due.map((r, i) => (
                    <tr key={i}>
                      <td className="mono">{r.script_number}</td>
                      <td><span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}><span className="sw" style={{ width: 7, height: 7, borderRadius: 2, background: window.RX.slVar(r.service_line), display: "inline-block" }} />{r.service_line}</span></td>
                      <td style={{ color: "var(--text-2)" }}>{r.queue || "—"}</td>
                      <td className="num">{r.days_lapsed}</td>
                    </tr>))}
                  {!due.length && <tr><td colSpan="4"><div className="empty">Nothing staged is due under the current filters.</div></td></tr>}
                </tbody>
              </table>
            </div>
            {bk.real_staged_due_now > due.length && <div className="note">Showing top {due.length} of {fmt(bk.real_staged_due_now)} (freshest lapse first).</div>}
          </Card>
        </>) : <Unavail what="Backlog metrics" />}
      </Card>
    </div>
  );
}
Object.assign(window, { Refill });
