/* Live Components — shared enhancements
 * Loaded via: <script type="text/babel" src="LiveComponents.jsx"></script>
 *
 * Provides: <LiveActivityClock/>, <AnimatedCounter to/>, <WhatsAppFloater/>, <CharidyEmbed/>
 */

/* ----- LiveActivityClock —--------------------------------------------
 * A ticker that surfaces live network activity. Cycles through events
 * with a brief pulse, like an institutional Bloomberg ticker.
 */
function LiveActivityClock({events, intervalMs = 5500}) {
  const list = events || [
    {t:'5:42 AM', city:'Petach Tikva', msg:'Bus #001 departed · 28 children boarding'},
    {t:'5:48 AM', city:'Carmiel',     msg:'Yael, age 7, boarded Route #047'},
    {t:'6:00 AM', city:'Bnei Brak',   msg:'Reb Eliyahu opened the classroom · 42 boys'},
    {t:'6:15 AM', city:'Modi\u2019in Illit', msg:'Hemshech mentor placed call · Tzvi, 14'},
    {t:'7:30 AM', city:'Yerushalayim', msg:'Lunch program loaded · 1,400 hot meals'},
    {t:'8:00 AM', city:'Be\u2019er Sheva', msg:'Modeh Ani · 312 children began the day'},
    {t:'10:14 AM', city:'Ashdod',      msg:'Donor in Brooklyn covered Miriam\u2019s coat'},
    {t:'11:02 AM', city:'Tel Aviv',    msg:'New family enrollment received · 4th grade'},
  ];
  const [idx, setIdx] = React.useState(0);
  const [pulse, setPulse] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => {
      setPulse(p => p + 1);
      setTimeout(() => setIdx(i => (i + 1) % list.length), 240);
    }, intervalMs);
    return () => clearInterval(id);
  }, [intervalMs, list.length]);
  const ev = list[idx];
  return (
    <div className="liveclock" key={pulse}>
      <span className="dot" aria-hidden="true"></span>
      <span className="time">{ev.t}</span>
      <span className="sep">·</span>
      <span className="city">{ev.city}</span>
      <span className="sep">·</span>
      <span className="msg">{ev.msg}</span>
    </div>
  );
}

/* ----- AnimatedCounter ----------------------------------------------
 * Counts up to `to` when scrolled into view. Honors prefers-reduced-motion.
 */
function AnimatedCounter({to, durationMs = 1600, prefix = '', suffix = '', decimals = 0, format = true}) {
  const ref = React.useRef(null);
  const [val, setVal] = React.useState(0);
  const [done, setDone] = React.useState(false);
  React.useEffect(() => {
    if (done) return;
    const reduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduced) { setVal(to); setDone(true); return; }
    const obs = new IntersectionObserver(entries => {
      if (entries[0].isIntersecting && !done) {
        const start = performance.now();
        const tick = (now) => {
          const t = Math.min(1, (now - start) / durationMs);
          const eased = 1 - Math.pow(1 - t, 3);
          setVal(to * eased);
          if (t < 1) requestAnimationFrame(tick); else setDone(true);
        };
        requestAnimationFrame(tick);
        obs.disconnect();
      }
    }, {threshold: 0.4});
    if (ref.current) obs.observe(ref.current);
    return () => obs.disconnect();
  }, [to, done, durationMs]);
  const display = format
    ? val.toLocaleString('en-US', {minimumFractionDigits: decimals, maximumFractionDigits: decimals})
    : val.toFixed(decimals);
  return <span ref={ref} className="counter">{prefix}{display}{suffix}</span>;
}

/* ----- WhatsAppFloater ----------------------------------------------
 * Floating button — bottom-right (bottom-left in RTL pages) with WhatsApp
 * deep link. Click reveals a small pre-message card.
 */
function WhatsAppFloater({number = '+972504123456', preset = 'Hi — I have a question about Chinuch Atzmai.'}) {
  const [open, setOpen] = React.useState(false);
  const url = `https://wa.me/${number.replace(/[^\d]/g,'')}?text=${encodeURIComponent(preset)}`;
  return (
    <div className="wa-floater">
      {open && (
        <div className="wa-card">
          <div className="wa-head">
            <div>
              <div className="nm">Chinuch Atzmai</div>
              <div className="meta">Reply usually within 1 hour</div>
            </div>
            <button className="x" onClick={() => setOpen(false)} aria-label="Close">×</button>
          </div>
          <div className="wa-body">
            <p>Have a question about a sponsorship, dedication, or our programs? Send us a message — we\u2019ll reply on WhatsApp.</p>
          </div>
          <a className="wa-cta" href={url} target="_blank" rel="noopener noreferrer">Start chat →</a>
        </div>
      )}
      <button className="wa-btn" onClick={() => setOpen(o => !o)} aria-label="WhatsApp">
        <svg viewBox="0 0 24 24" width="26" height="26" fill="currentColor"><path d="M17.5 14.4c-.3-.1-1.7-.8-2-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.3-.5-2.4-1.5-.9-.8-1.5-1.8-1.7-2.1-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5-.1-.1-.7-1.6-.9-2.2-.2-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.4 0 1.4 1 2.8 1.2 3 .1.2 2 3.1 4.9 4.4.7.3 1.2.5 1.6.6.7.2 1.3.2 1.8.1.6-.1 1.7-.7 1.9-1.4.2-.7.2-1.2.2-1.4-.1-.1-.3-.2-.6-.3zM12 2C6.5 2 2 6.5 2 12c0 1.7.4 3.3 1.2 4.7L2 22l5.4-1.4c1.3.7 2.9 1.2 4.6 1.2 5.5 0 10-4.5 10-10S17.5 2 12 2zm0 18.2c-1.6 0-3.1-.4-4.4-1.2l-.3-.2-3.2.8.9-3.1-.2-.3c-.9-1.4-1.3-3-1.3-4.6 0-4.5 3.6-8.2 8.2-8.2 4.5 0 8.2 3.6 8.2 8.2-.1 4.6-3.7 8.6-8.2 8.6z"/></svg>
      </button>
    </div>
  );
}

/* ----- CharidyEmbed --------------------------------------------------
 * Charidy-style live campaign progress + tier rail. Pure presentational
 * (no real Charidy SDK). Pass {raised, goal, donors, matchX, deadline, tiers}.
 */
function CharidyEmbed(props) {
  const {raised = 2184400, goal = 3000000, donors = 4217, matchX = '2x', deadline = '10 Tishrei · Yom Kippur', tiers} = props;
  const pct = Math.min(100, (raised / goal) * 100);
  const fmt = (n) => '$' + n.toLocaleString('en-US');
  const TT = tiers || [
    {amt: 180,   l: 'Chai',                d: 'One classroom kappara · 1 month of lunch'},
    {amt: 613,   l: 'Taryag',              d: 'A Hemshech mentor · two boys · one month'},
    {amt: 1800,  l: 'Chai pi Chai',        d: 'A child for a year · doubled in the books', featured: true},
    {amt: 5400,  l: 'Three Children',      d: 'Three children, full school year'},
    {amt: 18000, l: 'A Classroom',         d: 'A classroom for the year + plaque'},
    {amt: 50000, l: 'Bronze Tier',         d: 'A bus for the year + naming rights'},
  ];
  return (
    <div className="charidy">
      <div className="ch-head">
        <div>
          <div className="ch-kicker">Live campaign · matched {matchX}</div>
          <div className="ch-raised"><AnimatedCounter to={raised} prefix="$" /></div>
          <div className="ch-of">of {fmt(goal)} · {donors.toLocaleString()} donors</div>
        </div>
        <div className="ch-clock">
          <div className="ch-clock-lbl">Match closes</div>
          <div className="ch-clock-val">{deadline}</div>
          <div className="ch-clock-pulse"><span className="dot"/>Live</div>
        </div>
      </div>
      <div className="ch-bar"><div className="ch-bar-fill" style={{width: pct + '%'}}/></div>
      <div className="ch-tiers">
        {TT.map((t,i) => (
          <button key={i} className={'ch-tier ' + (t.featured ? 'featured' : '')}>
            <div className="amt">${t.amt.toLocaleString()}</div>
            <div className="l">{t.l}</div>
            <div className="d">{t.d}</div>
            <div className="cta">Give ${t.amt.toLocaleString()} →</div>
          </button>
        ))}
      </div>
      <div className="ch-foot">
        <span>Secure · 256-bit TLS · 501(c)(3) #13-2899191</span>
        <span className="trust">⚜ Approved by the Va\u2019ad Ha\u2019rabbanim</span>
      </div>
    </div>
  );
}

/* expose to other Babel script blocks */
Object.assign(window, {LiveActivityClock, AnimatedCounter, WhatsAppFloater, CharidyEmbed});
