// SMASH — Visual FX layer
// Inspired by tiltable hero decoration / marquee ribbons / floating sprites.
//
// Exports:
//   <Marquee>            horizontal scrolling word ribbon
//   <FloatingDecor>      a fixed-position SVG sprite that drifts with scroll
//   <DecorLayer>         drops a curated set of FloatingDecors into a section
//   Sprite icons: Ball, Racquet, RacquetFlat, Arrow, CourtMini, RegMark
//   useParallax()        hook — wires up the scroll-driven parallax sprites

const { useEffect, useRef, useState } = React;

// ──────────────────────────────────────────────────────────────────────────
// Sprite library — single-color, currentColor-aware SVGs
// ──────────────────────────────────────────────────────────────────────────
const Sprite = {
  ball: (s = 60) => (
    <svg width={s} height={s} viewBox="0 0 64 64" fill="none" style={{ overflow: 'visible' }}>
      <defs>
        <radialGradient id="ballG" cx="35%" cy="32%" r="65%">
          <stop offset="0%"  stopColor="#F4FCBE"/>
          <stop offset="55%" stopColor="#D9F378"/>
          <stop offset="100%" stopColor="#A7C649"/>
        </radialGradient>
      </defs>
      <circle cx="32" cy="32" r="28" fill="url(#ballG)" />
      <path d="M 6 24 Q 32 38 58 24" fill="none" stroke="rgba(15,76,58,0.45)" strokeWidth="1.6" strokeLinecap="round"/>
      <path d="M 6 40 Q 32 26 58 40" fill="none" stroke="rgba(15,76,58,0.45)" strokeWidth="1.6" strokeLinecap="round"/>
    </svg>
  ),

  racquet: (s = 100) => (
    <svg width={s} height={s * 2.6} viewBox="0 0 100 260" fill="none">
      {/* head */}
      <ellipse cx="50" cy="70" rx="42" ry="58" fill="none" stroke="currentColor" strokeWidth="4"/>
      <ellipse cx="50" cy="70" rx="38" ry="54" fill="none" stroke="currentColor" strokeWidth="0.6" opacity="0.45"/>
      {/* strings */}
      <g stroke="currentColor" strokeWidth="0.9" opacity="0.55">
        <line x1="14" y1="50" x2="86" y2="50"/>
        <line x1="14" y1="62" x2="86" y2="62"/>
        <line x1="14" y1="74" x2="86" y2="74"/>
        <line x1="14" y1="86" x2="86" y2="86"/>
        <line x1="14" y1="98" x2="86" y2="98"/>
        <line x1="32" y1="18" x2="32" y2="122"/>
        <line x1="42" y1="14" x2="42" y2="126"/>
        <line x1="50" y1="12" x2="50" y2="128"/>
        <line x1="58" y1="14" x2="58" y2="126"/>
        <line x1="68" y1="18" x2="68" y2="122"/>
      </g>
      {/* throat */}
      <path d="M 36 122 L 50 152 L 64 122" fill="none" stroke="currentColor" strokeWidth="4" strokeLinecap="round" strokeLinejoin="round"/>
      {/* handle */}
      <rect x="44" y="148" width="12" height="100" rx="6" fill="currentColor" opacity="0.85"/>
      {/* grip ribbing */}
      <g stroke="currentColor" strokeWidth="0.6" opacity="0.4">
        <line x1="44" y1="170" x2="56" y2="178"/>
        <line x1="44" y1="184" x2="56" y2="192"/>
        <line x1="44" y1="198" x2="56" y2="206"/>
        <line x1="44" y1="212" x2="56" y2="220"/>
      </g>
      <circle cx="50" cy="252" r="6" fill="currentColor"/>
    </svg>
  ),

  // A racquet rendered at an angle, used as a giant hero decoration
  racquetFlat: (s = 200) => (
    <svg width={s} height={s} viewBox="0 0 240 240" fill="none" style={{ overflow: 'visible' }}>
      <g transform="rotate(-35 120 120)">
        {/* head */}
        <ellipse cx="80" cy="80" rx="62" ry="78" fill="none" stroke="currentColor" strokeWidth="3.5"/>
        {/* strings */}
        <g stroke="currentColor" strokeWidth="0.7" opacity="0.45">
          <line x1="22" y1="50" x2="138" y2="50"/>
          <line x1="22" y1="65" x2="138" y2="65"/>
          <line x1="22" y1="80" x2="138" y2="80"/>
          <line x1="22" y1="95" x2="138" y2="95"/>
          <line x1="22" y1="110" x2="138" y2="110"/>
          <line x1="48" y1="8"  x2="48" y2="152"/>
          <line x1="64" y1="4"  x2="64" y2="156"/>
          <line x1="80" y1="2"  x2="80" y2="158"/>
          <line x1="96" y1="4"  x2="96" y2="156"/>
          <line x1="112" y1="8" x2="112" y2="152"/>
        </g>
        {/* throat / shaft */}
        <path d="M 60 154 L 80 182 L 100 154" fill="none" stroke="currentColor" strokeWidth="3.5" strokeLinejoin="round"/>
        <rect x="74" y="178" width="12" height="58" rx="6" fill="currentColor" opacity="0.9"/>
      </g>
    </svg>
  ),

  arrow: (s = 80) => (
    <svg width={s} height={s * 0.4} viewBox="0 0 80 32" fill="none">
      <path d="M 4 16 Q 30 4 60 16 M 50 8 L 60 16 L 50 24" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),

  arrowDown: (s = 40) => (
    <svg width={s} height={s} viewBox="0 0 40 40" fill="none">
      <path d="M 20 6 L 20 30 M 10 22 L 20 32 L 30 22" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  ),

  // Stylized mini court — top-down view
  courtMini: (s = 200) => (
    <svg width={s} height={s * 0.6} viewBox="0 0 200 120" fill="none">
      <rect x="6" y="6" width="188" height="108" stroke="currentColor" strokeWidth="1.2" fill="none"/>
      <line x1="100" y1="6" x2="100" y2="114" stroke="currentColor" strokeWidth="1.2"/>
      <rect x="40" y="36" width="120" height="48" stroke="currentColor" strokeWidth="0.9" fill="none"/>
      <line x1="40" y1="60" x2="160" y2="60" stroke="currentColor" strokeWidth="0.9"/>
      <line x1="6" y1="60" x2="40" y2="60" stroke="currentColor" strokeWidth="0.6" opacity="0.5"/>
      <line x1="160" y1="60" x2="194" y2="60" stroke="currentColor" strokeWidth="0.6" opacity="0.5"/>
    </svg>
  ),

  regMark: (s = 32) => (
    <svg width={s} height={s} viewBox="0 0 32 32" fill="none">
      <circle cx="16" cy="16" r="14" stroke="currentColor" strokeWidth="1.5" fill="none"/>
      <text x="16" y="21" textAnchor="middle"
            fontFamily="var(--font-body)" fontSize="14" fontWeight="500"
            fill="currentColor">R</text>
    </svg>
  ),

  scribble: (s = 60) => (
    <svg width={s * 2} height={s} viewBox="0 0 120 60" fill="none">
      <path d="M 4 30 Q 14 10 30 30 T 60 30 T 90 30 T 116 30"
            stroke="currentColor" strokeWidth="2.5" fill="none" strokeLinecap="round"/>
    </svg>
  ),
};

// ──────────────────────────────────────────────────────────────────────────
// MARQUEE — horizontal scrolling band of text or sprites.
//
// Brand-on rendition: huge Bebas SMASH (with the yellow dot still attached),
// separated by ® registration marks. Same vibe as Padel Chest's wordmark
// strip but using our type system.
//
// Props:
//   items     — array of strings | nodes
//   speed     — seconds per full loop (lower = faster). Default 60.
//   reverse   — bool, scroll right-to-left if false (default), left-to-right
//   size      — fontSize for text items (e.g. '92px')
//   gap       — px between items
//   tone      — 'dark'|'light'|'yellow' surface
// ──────────────────────────────────────────────────────────────────────────
function Marquee({ items, speed = 50, reverse = false, size = '88px', gap = 56, tone = 'dark', italics = false }) {
  // Repeat enough times to comfortably fill 200vw before the seam.
  const repeated = [...items, ...items, ...items, ...items, ...items, ...items];
  return (
    <div className={`marquee tone-${tone}`}>
      <div
        className={`marquee-track${reverse ? ' reverse' : ''}`}
        style={{ animationDuration: `${speed}s`, gap: `${gap}px` }}
      >
        {repeated.map((item, i) => (
          <span
            key={i}
            className="marquee-item"
            style={{ fontSize: size, fontStyle: italics ? 'italic' : 'normal' }}
          >
            {item}
          </span>
        ))}
      </div>
    </div>
  );
}

// SMASH wordmark for use inside a marquee — Bebas + yellow dot.
function MarqueeSmash({ dotColor = 'var(--ball-yellow)' }) {
  return (
    <span className="marquee-smash">
      SMASH
      <span className="marquee-smash-dot" style={{ background: dotColor }} />
    </span>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// FLOATING DECOR — a single SVG sprite that drifts with scroll.
//
// Placement: absolutely positioned within the parent (which must be
// `position: relative`). Uses scroll-driven translateY for parallax.
//
// Props:
//   top, left, right, bottom  — CSS anchor (any combination)
//   speed     — parallax multiplier (positive = moves up on scroll, negative = down)
//   rotate    — initial rotation in deg
//   spin      — rotation deg per page scrolled
//   float     — gentle CSS float animation on top of parallax
//   children  — the SVG sprite
//   color     — currentColor for the sprite
// ──────────────────────────────────────────────────────────────────────────
function FloatingDecor({
  top, left, right, bottom,
  speed = 0.2, rotate = 0, spin = 0,
  float: floatAnim = true, opacity = 1,
  color, zIndex = 1, children,
}) {
  const ref = useRef(null);
  const innerRef = useRef(null);
  useEffect(() => {
    if (speed === 0 && spin === 0) return;
    const el = ref.current;
    const inner = innerRef.current;
    if (!el || !inner) return;

    let raf;
    let curY = 0, curSpin = 0;      // smoothed (rendered) values
    let tgtY = 0, tgtSpin = 0;      // scroll-derived targets
    let running = true;

    const measure = () => {
      const r = el.getBoundingClientRect();
      const dy = (window.innerHeight / 2) - (r.top + r.height / 2);
      tgtY = dy * speed;
      tgtSpin = (window.scrollY * spin) / 1000;
    };

    const loop = () => {
      if (!running) return;
      // Critically-damped lerp — smooth follow, no overshoot, no jitter.
      curY    += (tgtY    - curY)    * 0.12;
      curSpin += (tgtSpin - curSpin) * 0.12;
      // Snap when extremely close to avoid sub-pixel churn.
      if (Math.abs(tgtY - curY) < 0.05) curY = tgtY;
      if (Math.abs(tgtSpin - curSpin) < 0.01) curSpin = tgtSpin;
      inner.style.transform =
        `translate3d(0, ${curY.toFixed(2)}px, 0) rotate(${curSpin.toFixed(2)}deg)`;
      raf = requestAnimationFrame(loop);
    };

    measure();
    curY = tgtY; curSpin = tgtSpin;   // start settled, no opening lurch
    const onScroll = () => measure();
    const onResize = () => measure();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onResize, { passive: true });
    raf = requestAnimationFrame(loop);
    return () => {
      running = false;
      if (raf) cancelAnimationFrame(raf);
      window.removeEventListener('scroll', onScroll);
      window.removeEventListener('resize', onResize);
    };
  }, [speed, spin]);

  const style = {
    top, left, right, bottom,
    color, opacity, zIndex,
    transform: `rotate(${rotate}deg)`,
  };

  return (
    <div
      ref={ref}
      className="floating-decor"
      style={style}
      aria-hidden="true"
    >
      <div className="floating-decor-inner" ref={innerRef}>
        <div className={`floating-decor-float${floatAnim ? ' float-anim' : ''}`}>
          {children}
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// REVEAL ON SCROLL — wrap any node to fade + slide it in
// Reuses the .reveal class already in site.css plus a stagger index.
// ──────────────────────────────────────────────────────────────────────────
function Reveal({ delay = 0, children, as: As = 'div', className = '', ...rest }) {
  const cls = `reveal${delay ? ` d${Math.min(delay, 4)}` : ''} ${className}`;
  return <As className={cls.trim()} {...rest}>{children}</As>;
}

// ──────────────────────────────────────────────────────────────────────────
// SCRAMBLE TEXT — single-word "draw-in" effect. Renders each character as a
// span so we can stagger them.
// ──────────────────────────────────────────────────────────────────────────
function StaggerText({ text, className = '', style }) {
  const chars = [...text];
  return (
    <span className={`stagger-text ${className}`} style={style}>
      {chars.map((c, i) => (
        <span key={i} style={{ animationDelay: `${i * 28}ms` }}>{c === ' ' ? '\u00A0' : c}</span>
      ))}
    </span>
  );
}

Object.assign(window, {
  Sprite, Marquee, MarqueeSmash, FloatingDecor, Reveal, StaggerText,
});

// ──────────────────────────────────────────────────────────────────────────
// Pre-configured marquee variants used by the landing
// ──────────────────────────────────────────────────────────────────────────
function BrandMarquee() {
  // Repeated SMASH wordmark + ® mark, alternating with the running tagline.
  const dot = (color) => <MarqueeSmash dotColor={color} />;
  const items = [
    dot('var(--ball-yellow)'),
    <span className="marquee-reg">®</span>,
    <span style={{ fontStyle: 'italic', opacity: 0.7 }}>сыграй больше</span>,
    <span className="marquee-reg">®</span>,
    dot('var(--ball-yellow)'),
    <span className="marquee-reg">®</span>,
    <span style={{ fontStyle: 'italic', opacity: 0.7 }}>теннис</span>,
    <span className="marquee-reg">®</span>,
    dot('var(--ball-yellow)'),
    <span className="marquee-reg">®</span>,
    <span style={{ fontStyle: 'italic', opacity: 0.7 }}>москва · 2026&nbsp;</span>,
    <span className="marquee-reg">®</span>,
  ];
  return <Marquee items={items} speed={42} gap={32} size="34px" tone="dark" />;
}

function SecondaryMarquee() {
  const items = [
    <span>NTRP 2.0</span>,
    <span className="marquee-dot">●</span>,
    <span>NTRP 3.0</span>,
    <span className="marquee-dot">●</span>,
    <span>NTRP 4.0</span>,
    <span className="marquee-dot">●</span>,
    <span>NTRP 5.0</span>,
    <span className="marquee-dot">●</span>,
    <span>NTRP 6.0+</span>,
    <span className="marquee-dot">●</span>,
    <span>хамовники · лужники · крылатское</span>,
    <span className="marquee-dot">●</span>,
  ];
  return <Marquee items={items} speed={55} reverse gap={28} size="34px" tone="yellow" />;
}

// ──────────────────────────────────────────────────────────────────────────
// SectionDecor — drops a section-specific set of floating sprites.
// Curated: keep only the largest atmospheric pieces (racquet silhouettes)
// and a single accent ball per section, max. No scribbles, no courts.
// ──────────────────────────────────────────────────────────────────────────
function SectionDecor({ variant = 'hero' }) {
  if (variant === 'hero') {
    return (
      <>
        <FloatingDecor top="12%" right="-6%" rotate={-18} speed={0.05} spin={20} float={false} opacity={0.10} color="var(--ball-yellow)" zIndex={1}>
          {Sprite.racquetFlat(680)}
        </FloatingDecor>
      </>
    );
  }
  if (variant === 'problem') {
    return (
      <>
        <FloatingDecor top="52%" left="3%" rotate={-14} speed={-0.10} spin={40} opacity={0.55} zIndex={1}>
          {Sprite.ball(28)}
        </FloatingDecor>
      </>
    );
  }
  if (variant === 'how') {
    return (
      <>
        <FloatingDecor top="-4%" right="-5%" rotate={28} speed={-0.06} opacity={0.10} color="var(--ball-yellow)" zIndex={1}>
          {Sprite.racquetFlat(520)}
        </FloatingDecor>
      </>
    );
  }
  if (variant === 'why') {
    return (
      <>
        <FloatingDecor top="-8%" left="-6%" rotate={-22} speed={-0.05} opacity={0.07} color="var(--ball-yellow)" zIndex={1}>
          {Sprite.racquetFlat(620)}
        </FloatingDecor>
      </>
    );
  }
  if (variant === 'product') {
    // Intentionally minimal — let the phone mockups carry this section.
    return null;
  }
  if (variant === 'cta') {
    return (
      <>
        <FloatingDecor top="5%" left="-8%" rotate={-22} speed={-0.10} color="var(--court-green)" opacity={0.07} zIndex={1}>
          {Sprite.racquetFlat(320)}
        </FloatingDecor>
        <FloatingDecor bottom="5%" right="-6%" rotate={18} speed={0.12} color="var(--court-green)" opacity={0.07} zIndex={1}>
          {Sprite.racquetFlat(240)}
        </FloatingDecor>
      </>
    );
  }
  return null;
}

window.BrandMarquee = BrandMarquee;
window.SecondaryMarquee = SecondaryMarquee;
window.SectionDecor = SectionDecor;
