/* global React */
// Rayu — Hero section
// Editorial-magazine treatment with full-bleed video bg, oversized serif headline,
// store CTAs at bottom-left, fine-print marquee at the bottom edge.

const { useState, useEffect, useRef } = React;

// Magnetize button — particles scatter around the label and snap to center on
// hover/touch (a native-React + CSS adaptation of the framer-motion original).
function MagnetizeButton({ href, children, className = "", particleCount = 14 }) {
  const [attracting, setAttracting] = useState(false);
  const particles = useRef(
    Array.from({ length: particleCount }, () => ({
      x: Math.random() * 130 - 65,
      y: Math.random() * 70 - 35,
    }))
  );
  return (
    <a
      href={href}
      className={`mag-btn ${attracting ? "on" : ""} ${className}`}
      onMouseEnter={() => setAttracting(true)}
      onMouseLeave={() => setAttracting(false)}
      onTouchStart={() => setAttracting(true)}
      onTouchEnd={() => setAttracting(false)}
    >
      {particles.current.map((p, i) => (
        <span
          key={i}
          className="mag-dot"
          style={{
            transform: attracting
              ? "translate(0px, 0px)"
              : `translate(${p.x}px, ${p.y}px)`,
            transitionDelay: `${(attracting ? i : particleCount - i) * 12}ms`,
          }}
        ></span>
      ))}
      <span className="mag-label">
        <svg className="mag-magnet" viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M6 3v7a6 6 0 0 0 12 0V3"></path>
          <path d="M6 7H2M22 7h-4"></path>
        </svg>
        {children}
      </span>
    </a>
  );
}

function useScrolled(threshold = 40) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const on = () => setScrolled(window.scrollY > threshold);
    on();
    window.addEventListener("scroll", on, { passive: true });
    return () => window.removeEventListener("scroll", on);
  }, [threshold]);
  return scrolled;
}

function Nav() {
  const scrolled = useScrolled(80);
  return (
    <header className={scrolled ? "nav solid" : "nav"}>
      <a href="#" className="nav-logo"><img src="assets/logo-white.png" alt="rayu.ai" /></a>
      <div className="nav-right">
        <nav className="nav-links">
          <a href="#daily">How it works</a>
          <a href="#device">Device</a>
          <a href="#voices">Community</a>
          <MagnetizeButton href="Order.html?v=Asub" className="nav-cta">Order the band</MagnetizeButton>
        </nav>
        <div className="nav-ireland" aria-label="Designed in Ireland">
          <svg className="nav-flag" viewBox="0 0 30 20" role="img" aria-hidden="true">
            <rect width="10" height="20" x="0" fill="#169B62" />
            <rect width="10" height="20" x="10" fill="#ffffff" />
            <rect width="10" height="20" x="20" fill="#FF883E" />
          </svg>
          <span className="nav-ireland-cap">DESIGNED N IRELAND</span>
        </div>
      </div>
    </header>);

}

function StoreBtn({ store }) {
  if (store === "apple") {
    return (
      <a className="store-btn" href="#" aria-label="Download on the App Store">
        <svg viewBox="0 0 24 24" width="26" height="26" fill="#fff">
          <path d="M17.05 12.04c-.03-2.83 2.31-4.19 2.42-4.26-1.32-1.93-3.38-2.2-4.11-2.23-1.75-.18-3.42 1.03-4.31 1.03-.9 0-2.27-1.01-3.74-.98-1.92.03-3.7 1.12-4.69 2.83-2 3.47-.51 8.6 1.43 11.42.95 1.38 2.08 2.93 3.55 2.88 1.43-.06 1.97-.92 3.69-.92 1.72 0 2.21.92 3.72.89 1.54-.03 2.51-1.4 3.44-2.79 1.09-1.6 1.54-3.15 1.56-3.23-.04-.02-2.98-1.14-3.01-4.54zM14.2 3.81C14.99 2.85 15.52 1.52 15.37.2c-1.13.05-2.5.75-3.32 1.7-.74.84-1.39 2.2-1.22 3.49 1.27.1 2.57-.64 3.37-1.58z" />
        </svg>
        <span className="store-txt">
          <small>Download on the</small>
          <b>App Store</b>
        </span>
      </a>);

  }
  return (
    <a className="store-btn" href="#" aria-label="Get it on Google Play">
      <svg viewBox="0 0 24 24" width="24" height="24">
        <defs>
          <linearGradient id="gp-a" x1="0" x2="0" y1="0" y2="1">
            <stop offset="0" stopColor="#00a0ff" /><stop offset="1" stopColor="#00e2ff" />
          </linearGradient>
          <linearGradient id="gp-b" x1="0" x2="1" y1="0" y2="0">
            <stop offset="0" stopColor="#ffce00" /><stop offset="1" stopColor="#ffa000" />
          </linearGradient>
          <linearGradient id="gp-c" x1="1" x2="0" y1="0" y2="1">
            <stop offset="0" stopColor="#ff3a44" /><stop offset="1" stopColor="#c31162" />
          </linearGradient>
          <linearGradient id="gp-d" x1="0" x2="1" y1="1" y2="0">
            <stop offset="0" stopColor="#32a071" /><stop offset="1" stopColor="#2da771" />
          </linearGradient>
        </defs>
        <path fill="url(#gp-a)" d="M3.3 2.7c-.3.3-.5.8-.5 1.4v15.8c0 .6.2 1.1.5 1.4l11.3-11.3z" />
        <path fill="url(#gp-b)" d="M18 13.6l-3-3-3.7 3 3.7 3 3-1.7c.9-.5.9-1.8 0-2.3z" />
        <path fill="url(#gp-c)" d="M14.6 21.4 3.3 10.1 11.3 13l3.4 3.4z" />
        <path fill="url(#gp-d)" d="M14.6 2.6 11.3 11l3-2.9L18 10.4c.9-.5.9-1.8 0-2.3z" />
      </svg>
      <span className="store-txt">
        <small>GET IT ON</small>
        <b>Google Play</b>
      </span>
    </a>);

}

// Resolve a source against inlined offline blobs (used by the standalone bundle).
function resolveHeroSrc(src) {
  if (typeof window === "undefined" || !window.__resources) return src;
  if (src === "assets/hero.mp4" && window.__resources.heroVideo) return window.__resources.heroVideo;
  if (src === "assets/hero-2.mp4" && window.__resources.heroVideo2) return window.__resources.heroVideo2;
  return src;
}

function Hero({ videoUrl }) {
  const videoRef = useRef(null);
  const heroRef = useRef(null);
  const [videoOk, setVideoOk] = useState(false);
  // Carousel of hero clips — plays each through, then advances to the next and loops.
  const playlist = ["assets/hero-2.mp4", videoUrl];
  const [clip, setClip] = useState(0);
  const resolvedUrl = resolveHeroSrc(playlist[clip] || videoUrl);

  // Reset to the first clip whenever the tweakable first video changes.
  useEffect(() => {setClip(0);}, [videoUrl]);

  useEffect(() => {
    if (!videoRef.current) return;
    const v = videoRef.current;
    v.playbackRate = 0.75;
    v.muted = true;
    v.volume = 0;
    const onPlay = () => setVideoOk(true);
    const onErr = () => {
      // Skip a broken clip rather than stalling the carousel.
      if (playlist.length > 1) setClip((c) => (c + 1) % playlist.length);else
      setVideoOk(false);
    };
    const onRate = () => {if (v.playbackRate !== 0.75) v.playbackRate = 0.75;};
    const onEnded = () => setClip((c) => (c + 1) % playlist.length);
    v.addEventListener("playing", onPlay);
    v.addEventListener("error", onErr);
    v.addEventListener("loadedmetadata", onRate);
    v.addEventListener("ended", onEnded);
    // Load + play the freshly-set source.
    v.load();
    const r = v.play();
    if (r && r.catch) r.catch(() => {});
    return () => {
      v.removeEventListener("playing", onPlay);
      v.removeEventListener("error", onErr);
      v.removeEventListener("loadedmetadata", onRate);
      v.removeEventListener("ended", onEnded);
    };
  }, [resolvedUrl]);

  // Pause the hero clip when it scrolls off-screen — frees the video decoder
  // for the heavy scroll-scrub clip further down the page (and saves power).
  // Uses scroll position rather than IntersectionObserver, which is unreliable
  // in some embedded webviews.
  useEffect(() => {
    const v = videoRef.current;
    const el = heroRef.current;
    if (!v || !el) return undefined;
    let offscreen = false;
    const onScroll = () => {
      const rect = el.getBoundingClientRect();
      const isOff = rect.bottom <= 0 || rect.top >= window.innerHeight;
      if (isOff && !offscreen) {
        offscreen = true;
        try { v.pause(); } catch (e) { /* noop */ }
      } else if (!isOff && offscreen) {
        offscreen = false;
        const r = v.play();
        if (r && r.catch) r.catch(() => {});
      }
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  return (
    <section ref={heroRef} className="hero" data-screen-label="Hero">
      {resolvedUrl ?
      <video
        ref={videoRef}
        className="hero-video"
        src={resolvedUrl}
        autoPlay
        muted
        playsInline
        preload="auto" /> :

      null}
      {!videoOk &&
      <div className="hero-placeholder">
          <div className="hero-placeholder-label">
            VIDEO · drop hero footage here
          </div>
        </div>
      }
      <div className="hero-veil"></div>
      <div className="hero-grain"></div>

      <div className="hero-inner">
        <h1 className="display hero-title">
          The nutritionist<br />
          that's <em>always</em> with you.
        </h1>
        <div className="hero-bottom">
          <p className="hero-sub">
            The tailored AI &amp; wearable, supporting you with your nutrition to hit
            those health goals. Everything your diet coach provides and much more,
            with you 24/7.
          </p>
          <div className="hero-ctas">
            <StoreBtn store="apple" />
            <StoreBtn store="google" />
          </div>
        </div>
      </div>

      <div className="hero-dots" role="tablist" aria-label="Hero videos">
        {playlist.map((_, i) =>
        <button
          key={i}
          className={i === clip ? "hero-dot on" : "hero-dot"}
          role="tab"
          aria-selected={i === clip}
          aria-label={`Show video ${i + 1}`}
          onClick={() => setClip(i)}>
        </button>
        )}
      </div>

      <div className="hero-fade"></div>
    </section>);

}

Object.assign(window, { Hero, Nav, StoreBtn });
