// Reusable visual primitives for The Book of Bad

const Stamp = ({ children, color, rot = -6, style = {} }) => (
  <span className="stamp" style={{ color: color || 'var(--red)', transform: `rotate(${rot}deg)`, ...style }}>
    {children}
  </span>
);

const SlamStamp = ({ children, color = 'var(--red)', rot = -8, delay = 0 }) => {
  const [shown, setShown] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const obs = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) setTimeout(() => setShown(true), delay); });
    }, { threshold: 0.4 });
    if (ref.current) obs.observe(ref.current);
    return () => obs.disconnect();
  }, [delay]);
  return (
    <span ref={ref} style={{
      display: 'inline-block',
      transform: shown ? `rotate(${rot}deg) scale(1)` : `rotate(${rot - 30}deg) scale(2.4)`,
      opacity: shown ? 1 : 0,
      transition: 'transform .35s cubic-bezier(.5,-0.4,.5,1.5), opacity .25s ease',
    }}>
      <span className="stamp" style={{ color, transform: 'none' }}>{children}</span>
    </span>
  );
};

// Hand-drawn arrow svg
const Arrow = ({ rotate = 0, color = 'var(--ink)', w = 80, style = {} }) => (
  <svg viewBox="0 0 100 60" width={w} style={{ transform: `rotate(${rotate}deg)`, ...style }}>
    <path d="M5 30 Q 30 5, 60 28 T 92 30" stroke={color} strokeWidth="4" fill="none" strokeLinecap="round" />
    <polygon points="92,30 80,22 80,38" fill={color} />
  </svg>
);

const HalftoneBlob = ({ size = 200, color = 'var(--red)', style = {} }) => (
  <div style={{
    width: size, height: size,
    backgroundImage: `radial-gradient(${color} 2px, transparent 2.5px)`,
    backgroundSize: '8px 8px',
    ...style,
  }} />
);

// Speech bubble
const Bubble = ({ children, color = 'var(--paper)', textColor = 'var(--ink)', tail = 'br', style = {} }) => {
  const tailMap = {
    bl: { left: 30, bottom: -16, transform: 'rotate(0deg)' },
    br: { right: 30, bottom: -16, transform: 'rotate(0deg) scaleX(-1)' },
    tl: { left: 30, top: -16, transform: 'rotate(180deg) scaleX(-1)' },
  };
  return (
    <div style={{
      position: 'relative',
      background: color,
      color: textColor,
      border: '4px solid var(--ink)',
      padding: '18px 22px',
      fontFamily: "'Luckiest Guy', sans-serif",
      fontSize: 20,
      lineHeight: 1.1,
      boxShadow: '5px 5px 0 var(--ink)',
      ...style,
    }}>
      {children}
      <div style={{
        position: 'absolute',
        width: 30, height: 22,
        background: color,
        borderRight: '4px solid var(--ink)',
        borderBottom: '4px solid var(--ink)',
        clipPath: 'polygon(0 0, 100% 0, 50% 100%)',
        ...tailMap[tail],
      }} />
    </div>
  );
};

// Hook: detect element entering viewport, add 'in' class
const useReveal = () => {
  React.useEffect(() => {
    const els = document.querySelectorAll('.reveal, .reveal-l, .reveal-r, .reveal-zoom');
    const obs = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) e.target.classList.add('in');
      });
    }, { threshold: 0.15 });
    els.forEach(el => obs.observe(el));
    return () => obs.disconnect();
  });
};

// Hook: scroll position
const useScrollY = () => {
  const [y, setY] = React.useState(0);
  React.useEffect(() => {
    const onScroll = () => setY(window.scrollY);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return y;
};

// Money rain absolute container
const MoneyRain = ({ count = 14 }) => {
  const bills = React.useMemo(() => Array.from({ length: count }, (_, i) => ({
    id: i,
    left: Math.random() * 100,
    top: Math.random() * 100,
    rot: (Math.random() * 60 - 30),
    delay: Math.random() * 4,
    duration: 4 + Math.random() * 3,
    label: ['$100', '$$$', '$50', '€', 'CASH'][Math.floor(Math.random() * 5)],
  })), [count]);
  return (
    <div className="money-rain">
      {bills.map(b => (
        <div key={b.id} className="bill" style={{
          left: `${b.left}%`,
          top: `${b.top}%`,
          ['--rot']: `${b.rot}deg`,
          animation: `billFloat ${b.duration}s ease-in-out ${b.delay}s infinite alternate`,
        }}>{b.label}</div>
      ))}
      <style>{`
        @keyframes billFloat {
          from { transform: translateY(0) rotate(var(--rot, 8deg)); }
          to { transform: translateY(-30px) rotate(calc(var(--rot, 8deg) + 10deg)); }
        }
      `}</style>
    </div>
  );
};

// Live ticker: cumulative $ stolen from pro athletes since Jan 1, 2026.
// Rate based on estimated annual losses of $1.005B – $2.010B (upper bound).
// Upper-bound breakdown: $167.5M/mo · $5,506,849/day · $229,452/hr · $3,824/min
// → $63.74/sec. Source: PCFI.org | Research Division.
// Counter is tracked in integer cents to avoid float drift.
const FraudTicker = () => {
  const RATE_PER_SEC = 63.74;
  const BASELINE_MS = Date.UTC(2026, 0, 1, 0, 0, 0);
  const computeCents = () => Math.max(0, Math.floor((Date.now() - BASELINE_MS) / 1000 * RATE_PER_SEC * 100));
  const [cents, setCents] = React.useState(computeCents);
  const [maxed, setMaxed] = React.useState(false);
  React.useEffect(() => {
    const id = setInterval(() => setCents(computeCents()), 2000);
    return () => clearInterval(id);
  }, []);
  React.useEffect(() => {
    if (!maxed) return;
    const onKey = (e) => { if (e.key === 'Escape') setMaxed(false); };
    window.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = prev;
    };
  }, [maxed]);
  const dollars = Math.floor(cents / 100);
  const cc = String(cents % 100).padStart(2, '0');
  const formatted = '$' + dollars.toLocaleString('en-US') + '.' + cc;

  const renderInner = (big) => (
    <>
      <button
        type="button"
        className="ft-maximize"
        onClick={() => setMaxed(!big)}
        aria-label={big ? 'Close enlarged ticker' : 'Open enlarged ticker'}
        title={big ? 'Close' : 'Enlarge'}
      >
        {big ? (
          <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
            <path d="M7 2 V7 H2 M9 2 V7 H14 M7 14 V9 H2 M9 14 V9 H14"
              stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="square" />
          </svg>
        ) : (
          <svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true">
            <path d="M2 2 H7 M2 2 V7 M14 2 H9 M14 2 V7 M2 14 H7 M2 14 V9 M14 14 H9 M14 14 V9"
              stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="square" />
          </svg>
        )}
      </button>
      <div className="ft-head">
        <span className="ft-pulse" />
        <span>LIVE · ATHLETE FRAUD</span>
      </div>
      <div className="ft-amount">{formatted}</div>
      <div className="ft-rate">~$2.01B / YR · ~$167.50M / MO · ~$38.50M / WK · ~$5.50M / DAY · ~$3,824.00 / MIN · ~$63.74 / SEC</div>
      <div className="ft-foot">STOLEN FROM PRO ATHLETES · HOCKEY ALUMNI ON THE LIST · SINCE JAN 1, 2026</div>
      <div className="ft-source">
        Source: <a href="https://pcfi.org" target="_blank" rel="noopener noreferrer">PCFI.org</a> · Research Division
        <a
          className="ft-learn"
          href="/research"
          onClick={(e) => {
            e.preventDefault();
            if (big) setMaxed(false);
            window.history.pushState(null, '', '/research');
            window.dispatchEvent(new PopStateEvent('popstate'));
          }}
        >
          Read the paper <span className="ft-learn-arrow">→</span>
        </a>
      </div>
    </>
  );

  return (
    <>
      <div className="fraud-ticker">{renderInner(false)}</div>
      {maxed && ReactDOM.createPortal(
        <div className="ft-modal" onClick={() => setMaxed(false)}>
          <div className="fraud-ticker fraud-ticker--big" onClick={(e) => e.stopPropagation()}>
            {renderInner(true)}
          </div>
        </div>,
        document.body
      )}
    </>
  );
};

// Hero CTA card that opens an interactive case.
// Pass `options=[{label,onClick,tag?}, …]` to render a chooser between
// multiple case files; otherwise pass `onClick` for a single-case button.
const CaseCTA = ({
  onClick,
  options,
  className = '',
  eyebrow = '★ INTERACTIVE CASE FILE ★',
  title,
  sub = 'Step into a real $20.00M fraud. Make the calls. Live with them.',
  buttonLabel = 'OPEN THE CASE',
}) => {
  const titleNode = title || (<>WHAT WOULD<br />YOU DO?</>);
  if (options && options.length) {
    return (
      <div className={`case-cta case-cta--dual ${className}`}>
        <div className="case-cta-eyebrow">{eyebrow}</div>
        <div className="case-cta-title">{titleNode}</div>
        <div className="case-cta-sub">{sub}</div>
        <div className="case-cta-options">
          {options.map((o, i) => (
            <button key={i} type="button" className="case-cta-btn" onClick={o.onClick}>
              <span className="case-cta-btn-label">
                {o.tag && <span className="case-cta-btn-tag">{o.tag}</span>}
                {o.label}
              </span>
              <span className="arrow">→</span>
            </button>
          ))}
        </div>
      </div>
    );
  }
  return (
    <button type="button" className={`case-cta ${className}`} onClick={onClick}>
      <div className="case-cta-eyebrow">{eyebrow}</div>
      <div className="case-cta-title">{titleNode}</div>
      <div className="case-cta-sub">{sub}</div>
      <div className="case-cta-btn">
        {buttonLabel} <span className="arrow">→</span>
      </div>
    </button>
  );
};

// Activation form for the case-study CTA — submits to FormSubmit.co
// (no backend required). On first submission, FormSubmit emails the
// configured address a one-time confirmation link; once confirmed,
// every future submit delivers as plain email to nhlaa@oware.com.
const ActivationForm = ({ source = 'case-study' }) => {
  const [status, setStatus] = React.useState('idle'); // 'idle' | 'sending' | 'sent' | 'error'
  const [err, setErr] = React.useState('');
  const onSubmit = async (e) => {
    e.preventDefault();
    const fd = new FormData(e.target);
    if (fd.get('_honey')) return; // honeypot tripped — silently drop bots
    setStatus('sending');
    setErr('');
    try {
      const res = await fetch('https://formsubmit.co/ajax/nhlaa@oware.com', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        body: JSON.stringify(Object.fromEntries(fd)),
      });
      if (!res.ok) throw new Error('HTTP ' + res.status);
      setStatus('sent');
    } catch (ex) {
      setErr(ex.message || 'Network error');
      setStatus('error');
    }
  };
  if (status === 'sent') {
    return (
      <div className="ic-form-success">
        <div className="ic-form-success-icon">✓</div>
        <div className="ic-form-success-title">YOU'RE ON THE LIST.</div>
        <div className="ic-form-success-sub">
          We received your details. Continuous monitoring goes live within 24 hours —
          watch <strong>nhlaa@oware.com</strong> for the activation email.
        </div>
      </div>
    );
  }
  return (
    <form className="ic-form" onSubmit={onSubmit} noValidate>
      <input type="hidden" name="_subject" value="NHLAA Athlete Awareness — new activation" />
      <input type="hidden" name="_captcha" value="false" />
      <input type="hidden" name="source" value={source} />
      <input className="ic-form-honey" type="text" name="_honey" tabIndex={-1} autoComplete="off" />
      <div className="ic-form-trust">
        ★ Currently monitoring <strong>$1.65B+</strong> in listed company revenue across the Athlete Awareness platform.
      </div>
      <div className="ic-form-note">Two emails. That's all we need to start.</div>
      <div className="ic-form-row">
        <label className="ic-form-field">
          <span className="ic-form-label">Player email <em>*</em></span>
          <input name="player_email" type="email" required autoComplete="email" />
        </label>
        <label className="ic-form-field">
          <span className="ic-form-label">Business email <em>*</em></span>
          <input name="business_email" type="email" required />
        </label>
      </div>
      <button type="submit" className="ic-cta-link ic-form-submit" disabled={status === 'sending'}>
        {status === 'sending' ? 'SENDING…' : (<>PROTECT YOUR INVESTMENT <span>→</span></>)}
      </button>
      {status === 'error' && (
        <div className="ic-form-error">
          Couldn't send — try again, or email <a href="mailto:nhlaa@oware.com">nhlaa@oware.com</a> directly.
        </div>
      )}
    </form>
  );
};

Object.assign(window, { Stamp, SlamStamp, Arrow, HalftoneBlob, Bubble, useReveal, useScrollY, MoneyRain, FraudTicker, CaseCTA, ActivationForm });
