// landing-core.jsx — shared helpers for the Ssup landing page.
// Reveal (scroll-in), PhoneMock (scaled real app screen), StoreButtons, parallax + nav hooks.

const { useState, useEffect, useRef } = React;

// ── scroll-in reveal (manual viewport check + guaranteed final
//    state). IntersectionObserver and the CSS transition timeline
//    can be paused inside preview iframes, so we (a) compute
//    in-view ourselves and (b) pin the final visible state via
//    setTimeout, which always runs. Capable browsers still animate. ──
function Reveal({ children, delay, as = 'div', className = '', eager, style }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const force = () => { el.style.transition = 'none'; el.style.opacity = '1'; el.style.transform = 'none'; };
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      setSeen(true); force(); return;
    }
    let raf = 0, done = false, pin = 0;
    const cleanup = () => {
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onScroll);
      window.removeEventListener('load', onScroll);
      cancelAnimationFrame(raf);
    };
    const reveal = () => {
      if (done) return;
      done = true;
      setSeen(true);
      cleanup();
      // guarantee the final visible state even if the CSS transition
      // timeline never advances (happens inside some preview iframes)
      pin = setTimeout(force, 820);
    };
    const check = () => {
      if (done) return;
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      if (r.top < vh * 0.92 && r.bottom > -40) reveal();
    };
    const onScroll = () => { cancelAnimationFrame(raf); raf = requestAnimationFrame(check); };
    if (eager) {
      requestAnimationFrame(reveal);
      return () => { clearTimeout(pin); cleanup(); };
    }
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    window.addEventListener('load', onScroll);
    requestAnimationFrame(check);
    const t1 = setTimeout(check, 160);
    const t2 = setTimeout(check, 480);
    const t3 = setTimeout(check, 900);
    // safety net: never leave content stuck hidden if scroll never fires
    const fb = setTimeout(reveal, 2000);
    return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); clearTimeout(fb); clearTimeout(pin); cleanup(); };
  }, []);
  const Tag = as;
  const cls = `lp-reveal ${delay ? 'lp-d' + delay : ''} ${eager ? 'lp-eager' : ''} ${seen ? 'lp-in' : ''} ${className}`;
  return <Tag ref={ref} className={cls} style={style}>{children}</Tag>;
}

// ── parallax: translateY by scroll, gated to in-view ────────
function useParallax(speed = 0.08) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el || (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches)) return;
    // capture the element's resting transform (e.g. CSS rotation) so we
    // append parallax to it instead of clobbering it
    const computed = getComputedStyle(el).transform;
    const base = (el.dataset.baseTransform && el.dataset.baseTransform.trim())
      ? el.dataset.baseTransform
      : (computed && computed !== 'none' ? computed : '');
    let raf = 0;
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        const rect = el.getBoundingClientRect();
        const mid = rect.top + rect.height / 2 - window.innerHeight / 2;
        el.style.transform = `${base} translateY(${(-mid * speed).toFixed(1)}px)`;
      });
    };
    // note: do NOT apply on mount — keep the composition at its designed
    // position until the user actually scrolls (avoids a load-time jump)
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => { window.removeEventListener('scroll', onScroll); cancelAnimationFrame(raf); };
  }, [speed]);
  return ref;
}

// ── floating phone mock — renders a real app screen scaled ──
function PhoneMock({ children, width = 300, className = '', style = {}, parallax, glow }) {
  const pref = useParallax(typeof parallax === 'number' ? parallax : 0.05);
  const ref = parallax ? pref : null;
  return (
    <div ref={ref} className={`lp-phone lp-parallax ${className}`} style={{ '--pw': width + 'px', ...style }}
      data-base-transform={style.transform || ''}>
      {glow ? <div className="lp-phone-glow"></div> : null}
      <div className="lp-phone-inner">
        <S2Screen>{children}</S2Screen>
      </div>
    </div>
  );
}

// ── app store buttons ───────────────────────────────────────
function AppleGlyph() {
  return (
    <svg width="22" height="26" viewBox="0 0 22 26" fill="currentColor" aria-hidden="true">
      <path d="M17.6 13.6c0-3 2.4-4.4 2.5-4.5-1.4-2-3.5-2.3-4.2-2.3-1.8-.2-3.5 1-4.4 1-.9 0-2.3-1-3.8-1-2 0-3.8 1.1-4.8 2.9-2 3.6-.5 8.9 1.5 11.8 1 1.4 2.1 3 3.6 2.9 1.4-.1 2-.9 3.7-.9s2.2.9 3.8.9 2.5-1.4 3.5-2.8c1.1-1.6 1.5-3.1 1.6-3.2-.1 0-3-1.2-3-4.5zM14.8 4.9c.8-1 1.3-2.3 1.2-3.6-1.1 0-2.5.8-3.3 1.7-.7.8-1.4 2.2-1.2 3.4 1.3.1 2.5-.6 3.3-1.5z"/>
    </svg>
  );
}
function PlayGlyph() {
  return (
    <svg width="22" height="24" viewBox="0 0 22 24" aria-hidden="true">
      <path d="M2 1.5 14.5 12 2 22.5c-.5.3-1.2 0-1.2-.7V2.2c0-.7.7-1 1.2-.7z" fill="#1E8FFF"/>
      <path d="M2 1.5 14.5 12 2 22.5c-.5.3-1.2 0-1.2-.7V2.2c0-.7.7-1 1.2-.7z" fill="url(#pg1)"/>
      <path d="m14.5 12 3.6-3 3 1.7c.9.5.9 1.8 0 2.3l-3 1.7-3.6-2.7z" fill="#C9F73A"/>
      <path d="M.8 1.5 11.5 12 .8 22.5c-.3-.2-.5-.5-.5-1V2.5c0-.5.2-.8.5-1z" fill="#34D0FF"/>
      <path d="m11.5 12 3-3.2 6 3.4c.8.5.8 1.6 0 2.1l-6 3.4-3-2.9z" fill="#FFD43B"/>
      <path d="M.8 1.5 11.5 12 14.6 9 1.9.9C1.5.6.8.8.8 1.5z" fill="#3DDC84"/>
      <path d="M.8 22.5 11.5 12l3.1 3-12.7 8.1c-.6.3-1.1 0-1.1-.6z" fill="#F2495C"/>
    </svg>
  );
}

function StoreButtons({ ghostSecond }) {
  return (
    <div className="lp-btnrow">
      <a className="lp-store" href="#download">
        <AppleGlyph />
        <span><small>Download on the</small><b>App Store</b></span>
      </a>
      <a className={'lp-store' + (ghostSecond ? ' lp-store-ghost' : '')} href="#download">
        <PlayGlyph />
        <span><small>Get it on</small><b>Google Play</b></span>
      </a>
    </div>
  );
}

Object.assign(window, { Reveal, useParallax, PhoneMock, StoreButtons, AppleGlyph, PlayGlyph });
