// ─── ¡eso! site shared building blocks ──────────────────────
// Identity tokens, ExclamMark, BleedMarks, photo helpers, scroll-reveal hook.

const ESO = {
  cream: '#F8F4E8', paper: '#FFFFFF', ink: '#1A1208',
  red: '#C84D2C', redDeep: '#A33D22',
  yellow: '#DCE21E', lime: '#DCE21E', muted: 'rgba(26, 18, 8, 0.58)',
  rule: 'rgba(26, 18, 8, 0.16)',
};

// ── ExclamMark ─────────────────────────────────────────────
// `which` = "open" → ¡, "close" → !
function ExclamMark({ which = 'close', size = 80, color = ESO.red, style = {} }) {
  const w = size * 0.20;
  const h = size;
  const stem  = h * 0.62;
  const dotR  = w * 0.34;
  const dotY  = which === 'open' ? h * 0.16 : h * 0.84;
  const stemY = which === 'open' ? h * 0.30 : 0;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} width={w} height={h}
         style={{ display: 'block', ...style }}>
      <rect x={w * 0.18} y={stemY} width={w * 0.64} height={stem}
            fill={color} rx={w * 0.04} />
      <circle cx={w / 2} cy={dotY} r={dotR} fill={color} />
    </svg>
  );
}

// ── BleedMarks ─────────────────────────────────────────────
// ¡ top-left + ! bottom-right, split half-off the page edge
function BleedMarks({
  show = true, color = ESO.lime, size = 320, bleed = 0.5, zIndex = 1,
} = {}) {
  if (!show) return null;
  const w = size * 0.20;
  const offX = -w * bleed;
  return (
    <React.Fragment>
      <div style={{
        position: 'absolute', top: 0, left: offX, zIndex,
        pointerEvents: 'none',
      }}>
        <ExclamMark which="open" size={size} color={color} />
      </div>
      <div style={{
        position: 'absolute', bottom: 0, right: offX, zIndex,
        pointerEvents: 'none',
      }}>
        <ExclamMark which="close" size={size} color={color} />
      </div>
    </React.Fragment>
  );
}

// ── CoachPhoto ─────────────────────────────────────────────
// The Jorge & Ariana photo — two crops:
//   "wide" → both coaches, full-bleed strip with parallax-ready ratio
//   "ariana" / "jorge" → single face crop
const PHOTO_SRC = 'website-assets/jorge_ariana.png';

function CoachPhoto({ crop = 'wide', height = 360, parallaxY = 0 }) {
  // 1920x1080 source. Approx face centers in %:
  //   Ariana ~ (24%, 33%), Jorge ~ (75%, 32%)
  const cropMap = {
    wide:   { bgSize: 'cover',   bgPos: '50% 28%' },
    ariana: { bgSize: '260% auto', bgPos: '24% 33%' },
    jorge:  { bgSize: '260% auto', bgPos: '75% 32%' },
  };
  const c = cropMap[crop] || cropMap.wide;
  return (
    <div style={{
      width: '100%', height, position: 'relative', overflow: 'hidden',
      background: ESO.ink,
    }}>
      <div style={{
        position: 'absolute', inset: '-12% -2% -2% -2%',
        backgroundImage: `url(${PHOTO_SRC})`,
        backgroundSize: c.bgSize,
        backgroundPosition: c.bgPos,
        backgroundRepeat: 'no-repeat',
        filter: 'contrast(1.04) saturate(0.95)',
        transform: `translateY(${parallaxY}px)`,
        willChange: 'transform',
      }} />
      {/* Subtle vignette to anchor type when overlaid */}
      <div style={{
        position: 'absolute', inset: 0,
        background: 'linear-gradient(180deg, rgba(31,26,23,0.0) 50%, rgba(31,26,23,0.42) 100%)',
        pointerEvents: 'none',
      }} />
    </div>
  );
}

// ── useReveal ──────────────────────────────────────────────
// IntersectionObserver hook — adds .in to elements w/ .reveal once they enter view.
function useRevealOnScroll() {
  React.useEffect(() => {
    const els = document.querySelectorAll('.reveal');
    if (!els.length) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  });
}

// ── useScrollY ─────────────────────────────────────────────
// Light-weight scroll position hook for parallax. Throttled via rAF.
function useScrollY() {
  const [y, setY] = React.useState(0);
  React.useEffect(() => {
    let raf = 0;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        setY(window.scrollY || 0);
        raf = 0;
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);
  return y;
}

Object.assign(window, {
  ESO, ExclamMark, BleedMarks, CoachPhoto,
  useRevealOnScroll, useScrollY,
});
