/* ============================================================
   BeneCare RPM — calculator v2.1 (shared, AKS-safe)
   The ONLY place with numbers. Doctor-side economics only.
   Page shows the UPPER ("up to") figure; model still computes
   both bounds (netLow kept for the full range on a demo call).
   First screen is simple: slider + big net + annual; the
   billing − fee breakdown lives under a disclosure.
   ============================================================ */

// === DOCTOR-FACING PLACEHOLDERS — replace with approved pricing ===
// This is the DOCTOR's side. None of our cost / margin / split / nurse-ratio
// lives here, and the fee is never broken into components.
const CONFIG = {
  GROSS_RPM_PER_PATIENT_MONTH: 100,   // illustrative Medicare RPM billing potential / enrolled patient (public CMS rates)
  CCM_ADDON_PER_PATIENT_MONTH:  30,   // extra billing potential per CCM-enrolled patient
  SERVICE_FEE_PER_PATIENT_MONTH: 40,  // flat fee the practice pays per enrolled patient (their cost — fine to show)

  // realistic share of ENROLLED patients that successfully bill in a given month
  // (16-day device thresholds, copay drop-off, ramp). Drives the low–high range.
  UTILIZATION_LOW: 0.70,
  UTILIZATION_HIGH: 0.90,

  MIN_PATIENTS: 10, MAX_PATIENTS: 1000, STEP: 10, DEFAULT_PATIENTS: 150,
  MIN_CCM_PCT: 0, MAX_CCM_PCT: 100, DEFAULT_CCM_PCT: 40, // % of panel eligible & enrolled in CCM
  CURRENCY: "USD",

  // staffing translation for the "What this means for your team" line (placeholders)
  MINUTES_PER_REVIEW: 5,     // clinician minutes per enrolled patient per month
  FTE_HOURS_PER_MONTH: 160,  // to convert clinician-hours into FTE

  // --- brand / wiring (single source of truth) ---
  BRAND: {
    email: "hello@benecarerpm.com", // TODO: replace with real inbox
    phone: "",                       // hidden until a real number exists
    legal: "BeneCare",               // TODO: confirm legal entity name
  },
  LEAD_ENDPOINT: "/api/lead",        // TODO: replace with real endpoint / form service
  SAMPLE_AUDIO: "",                  // TODO: add real 30-sec voice-assistant sample (mp3 url)
};

function compute(patients, ccmPct) {
  const ccmFrac = ccmPct / 100;
  const grossPP = CONFIG.GROSS_RPM_PER_PATIENT_MONTH + CONFIG.CCM_ADDON_PER_PATIENT_MONTH * ccmFrac;
  const fee     = CONFIG.SERVICE_FEE_PER_PATIENT_MONTH;
  const realizedLow  = patients * grossPP * CONFIG.UTILIZATION_LOW;
  const realizedHigh = patients * grossPP * CONFIG.UTILIZATION_HIGH;
  const feeMonthly   = patients * fee;
  return {
    realizedLow, realizedHigh, feeMonthly,
    netLow:  realizedLow  - feeMonthly,   // kept for full range on a demo call — not shown on page
    netHigh: realizedHigh - feeMonthly,
    annualLow:  (realizedLow  - feeMonthly) * 12,
    annualHigh: (realizedHigh - feeMonthly) * 12,
  };
}

const DISCLAIMER =
  "Illustrative estimate, not a guarantee of payment — actual Medicare reimbursement depends on your MAC " +
  "locality, patient eligibility, and correct billing. Full details in the footer.";

// staffing translation for the "What this means for your team" line
function staffing(patients) {
  const hrs = (patients * CONFIG.MINUTES_PER_REVIEW) / 60;
  const fte = hrs / CONFIG.FTE_HOURS_PER_MONTH;
  return { hrs: Math.round(hrs), fte: fte < 0.1 ? "<0.1" : fte.toFixed(1) };
}

const fmtUSD = (n) => "$" + Math.round(n).toLocaleString("en-US");
const roundK = (n) => Math.round(n / 1000) * 1000;
// rounded UPPER net for the hero pill, e.g. { up: 9000 }
function netPill(patients, ccmPct) {
  const r = compute(patients, ccmPct);
  return { up: roundK(r.netHigh) };
}

// smooth count-up — rAF for animation, with a timer safety-net so the
// final value ALWAYS lands even when rAF is throttled (unfocused iframe).
function useCountUp(value, dur) {
  const D = dur || 450;
  const [disp, setDisp] = React.useState(value);
  const prev = React.useRef(value);
  React.useEffect(() => {
    const from = prev.current, to = value, start = performance.now();
    let raf, settled = false;
    const finish = () => {
      if (settled) return;
      settled = true; prev.current = to; setDisp(to);
    };
    const tick = (t) => {
      const p = Math.min(1, (t - start) / D);
      const e = 1 - Math.pow(1 - p, 3);
      setDisp(from + (to - from) * e);
      if (p < 1) raf = requestAnimationFrame(tick); else finish();
    };
    raf = requestAnimationFrame(tick);
    const safety = setTimeout(finish, D + 80);
    return () => { cancelAnimationFrame(raf); clearTimeout(safety); };
  }, [value]);
  return disp;
}

function Money(props) {
  const d = useCountUp(props.value);
  return React.createElement("span", { className: props.className }, fmtUSD(d));
}

// small, accessible tooltip — hover + keyboard focus
function Tip(props) {
  return (
    <span className="tip">
      <button type="button" className="tip-btn" aria-label={props.label || "More info"}>?</button>
      <span className="tip-pop" role="tooltip">{props.text}</span>
    </span>
  );
}

function Calculator(props) {
  const variant = props.variant || "A";
  const split = props.split === true;
  // controlled if patients/ccmPct provided, else internal state
  const [pInt, setPInt] = React.useState(CONFIG.DEFAULT_PATIENTS);
  const [cInt, setCInt] = React.useState(CONFIG.DEFAULT_CCM_PCT);
  const patients = props.patients != null ? props.patients : pInt;
  const ccmPct   = props.ccmPct   != null ? props.ccmPct   : cInt;
  const setPatients = props.onPatients || setPInt;
  const setCcm      = props.onCcm      || setCInt;

  // breakdown disclosure
  const [open, setOpen] = React.useState(false);
  const bdRef = React.useRef(null);
  const [bdH, setBdH] = React.useState(0);
  React.useEffect(() => {
    setBdH(open && bdRef.current ? bdRef.current.scrollHeight : 0);
  }, [open, patients, ccmPct]);

  const r = compute(patients, ccmPct);
  const pPct = ((patients - CONFIG.MIN_PATIENTS) / (CONFIG.MAX_PATIENTS - CONFIG.MIN_PATIENTS)) * 100;

  const Controls = (
    <div className="calc-controls">
      <div className="calc-sliderhead">
        <label htmlFor={"sl-" + variant}>Chronic-care patients you'd put on monitoring</label>
        <span className="calc-pcount">{patients.toLocaleString("en-US")}<small>patients</small></span>
      </div>
      <input
        id={"sl-" + variant} type="range"
        min={CONFIG.MIN_PATIENTS} max={CONFIG.MAX_PATIENTS} step={CONFIG.STEP}
        value={patients}
        aria-label="Chronic-care patients you'd put on monitoring"
        aria-valuetext={patients + " patients"}
        onChange={(e) => setPatients(Number(e.target.value))}
        style={{ "--pct": pPct + "%" }}
      />
      <div className="calc-scale"><span>10</span><span>1,000</span></div>

      {!props.hideCcm && (
      <div className="calc-ccm">
        <div className="calc-ccm-head">
          <label htmlFor={"ccm-" + variant}>
            Share enrolled in CCM
            <Tip label="What's CCM?" text="Chronic Care Management — an optional Medicare service some of your patients qualify for, billable on top of monitoring." />
          </label>
          <span className="calc-ccmval">{ccmPct}%</span>
        </div>
        <input
          id={"ccm-" + variant} type="range"
          min={CONFIG.MIN_CCM_PCT} max={CONFIG.MAX_CCM_PCT} step={5}
          value={ccmPct}
          aria-label="Share of panel enrolled in Chronic Care Management"
          aria-valuetext={ccmPct + " percent"}
          onChange={(e) => setCcm(Number(e.target.value))}
          style={{ "--pct": ccmPct + "%" }}
        />
      </div>
      )}
    </div>
  );

  const Readout = (
    <div className="calc-readout">
      {/* first-screen headline: big net, no breakdown */}
      <div className="calc-net">
        <div className="calc-netlabel">Your estimated net</div>
        <div className="calc-netline">
          <span className="upto">up to</span>
          <Money className="calc-netnum" value={r.netHigh} /><span className="u">/mo</span>
        </div>
        <div className="calc-annual">
          <span className="a-label">Estimated annual net</span>
          <span className="a-num"><span className="upto-sm">up to</span> <Money value={r.annualHigh} /><span className="u">/yr</span></span>
        </div>
      </div>

      {/* the one hard cost + the staffing reality — both on the first screen */}
      <div className="calc-facts">
        <div className="calc-fact">
          <span className="cf-label">BeneCare service fee</span>
          <span className="cf-val"><Money value={r.feeMonthly} /><small>/mo</small> <em>(${CONFIG.SERVICE_FEE_PER_PATIENT_MONTH}/patient)</em></span>
        </div>
      </div>

      {props.ctaLabel && (
        <div className="calc-cta-wrap">
          {props.ctaLead && <p className="calc-cta-lead">{props.ctaLead}</p>}
          <a className="calc-cta" href={props.ctaHref ? props.ctaHref + "?patients=" + patients : "#contact"} onClick={props.onCta}>
            {props.ctaLabel}<span aria-hidden="true"> →</span>
          </a>
        </div>
      )}

      <p className="calc-foot">Estimated at full enrollment — most practices get there within a few months.</p>

      {/* progressive disclosure — the billing − fee math for the office manager */}
      <button type="button" className={"calc-disclosure" + (open ? " open" : "")}
              aria-expanded={open} onClick={() => setOpen((v) => !v)}>
        How this is calculated <span className="d-chev" aria-hidden="true">▾</span>
      </button>
      <div className="calc-breakdown" style={{ height: bdH }}>
        <div className="bd-inner" ref={bdRef}>
          <div className="calc-row">
            <span className="label">Estimated Medicare billing potential</span>
            <span className="val plus"><span className="upto-tiny">up to</span> <Money value={r.realizedHigh} /><small>/mo</small></span>
          </div>
          <div className="calc-row">
            <span className="label">− BeneCare service fee</span>
            <span className="val minus"><Money value={r.feeMonthly} /><small>/mo</small></span>
          </div>
          <div className="calc-rule"></div>
          <div className="calc-row total">
            <span className="label">= Your estimated net</span>
            <span className="val net"><span className="upto-tiny">up to</span> <Money value={r.netHigh} /><small>/mo</small></span>
          </div>
        </div>
      </div>

      <p className="calc-disc">{DISCLAIMER}</p>
    </div>
  );

  if (split) {
    return (
      <div className={"calc calc--" + variant}>
        {Controls}
        <div className="calc-divider"></div>
        {Readout}
      </div>
    );
  }
  return (
    <div className={"calc calc--" + variant}>
      {Controls}
      {Readout}
    </div>
  );
}

window.Calculator = Calculator;
window.CONFIG = CONFIG;
window.compute = compute;
window.netPill = netPill;
window.fmtUSD = fmtUSD;
