// shared.jsx — small reusable primitives for CAJE Collective

const { useEffect, useRef, useState, useMemo, useCallback } = React;

/* ----------------- Responsive hook ----------------- */
// Returns true when viewport width is at/below the breakpoint (default 768 = mobile).
function useIsMobile(bp = 768) {
  const [m, setM] = useState(() => typeof window !== 'undefined' && window.innerWidth <= bp);
  useEffect(() => {
    const on = () => setM(window.innerWidth <= bp);
    on();
    window.addEventListener('resize', on);
    return () => window.removeEventListener('resize', on);
  }, [bp]);
  return m;
}

/* ----------------- Reveal on scroll ----------------- */
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) 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 -60px 0px' });
    el.querySelectorAll('.reveal').forEach(n => io.observe(n));
    return () => io.disconnect();
  }, []);
  return ref;
}

/* ----------------- CAJE Wordmark ----------------- */
function Wordmark({ size = 'md', inverse = false, mono = false }) {
  const sizes = {
    sm: { caje: 16, sub: 7.5, gap: 6, letter: 0.42 },
    md: { caje: 22, sub: 8.5, gap: 8, letter: 0.5 },
    lg: { caje: 42, sub: 11, gap: 14, letter: 0.6 },
    xl: { caje: 80, sub: 14, gap: 22, letter: 0.7 },
  };
  const s = sizes[size];
  const color = inverse ? '#F5F0E6' : '#111111';
  const sub = inverse ? 'rgba(245,240,230,0.65)' : 'rgba(17,17,17,0.55)';
  const ruleColor = mono ? color : '#B89A79';

  return (
    <div style={{ display: 'inline-flex', flexDirection: 'column', alignItems: 'center', gap: s.gap, lineHeight: 1, userSelect: 'none' }}>
      <div style={{
        fontFamily: 'EB Garamond, serif',
        fontWeight: 400,
        fontSize: s.caje,
        letterSpacing: `${s.letter}em`,
        color,
        paddingLeft: `${s.letter}em`, // optical
        whiteSpace: 'nowrap',
      }}>
        C A J E
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: s.gap, width: '100%' }}>
        <div style={{ flex: 1, height: 1, background: ruleColor, opacity: 0.7 }} />
        <div style={{
          fontFamily: 'Inter, sans-serif',
          fontSize: s.sub,
          letterSpacing: '0.36em',
          fontWeight: 400,
          color: sub,
          textTransform: 'uppercase',
          whiteSpace: 'nowrap',
        }}>
          Collective
        </div>
        <div style={{ flex: 1, height: 1, background: ruleColor, opacity: 0.7 }} />
      </div>
    </div>
  );
}

/* ----------------- Monogram (circular C) ----------------- */
function Monogram({ size = 54, inverse = false }) {
  const fg = inverse ? '#F5F0E6' : '#111111';
  const bronze = '#B89A79';
  return (
    <svg width={size} height={size} viewBox="0 0 100 100" style={{ display: 'block' }}>
      <circle cx="50" cy="50" r="48" fill="none" stroke={bronze} strokeWidth="0.6" />
      <circle cx="50" cy="50" r="40" fill="none" stroke={fg} strokeWidth="0.4" opacity="0.25" />
      <text x="50" y="64" textAnchor="middle"
        fontFamily="EB Garamond, serif" fontStyle="italic" fontWeight="400"
        fontSize="48" fill={fg} letterSpacing="0">C</text>
    </svg>
  );
}

/* ----------------- CTA button ----------------- */
function CTA({ children, onClick, dark = false, small = false, href }) {
  const style = {
    padding: small ? '14px 24px' : '18px 32px',
    fontSize: small ? 10 : 11,
    background: dark ? '#111' : 'transparent',
    color: dark ? '#F5F0E6' : '#111',
    borderColor: dark ? '#111' : '#B89A79',
  };
  const content = (
    <>
      <span>{children}</span>
      <span className="cta-arrow" aria-hidden />
    </>
  );
  if (href) {
    return <a className="cta" style={style} href={href} onClick={onClick}>{content}</a>;
  }
  return <button className="cta" style={style} onClick={onClick}>{content}</button>;
}

/* ----------------- Eyebrow (numbered section header) ----------------- */
function Eyebrow({ num, label, align = 'left' }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 14,
      justifyContent: align === 'center' ? 'center' : 'flex-start',
    }}>
      {num && (
        <span className="numeral" style={{ fontSize: 15 }}>
          {num}
        </span>
      )}
      <span style={{ height: 1, width: 36, background: '#B89A79', opacity: 0.7 }} />
      <span className="eyebrow">{label}</span>
    </div>
  );
}

/* ----------------- Section headline (serif italic) ----------------- */
function Headline({ children, size = 'lg', as = 'h2', style = {} }) {
  const sizes = {
    sm: 38, md: 56, lg: 76, xl: 104, xxl: 140,
  };
  const Tag = as;
  return (
    <Tag className="display" style={{
      fontSize: sizes[size],
      ...style,
    }}>
      {children}
    </Tag>
  );
}

/* ----------------- Image with Ken Burns ----------------- */
function KBImage({ src, alt, placeholder, ratio = '4/5', onClick, overlay = 0 }) {
  return (
    <div className="kb-wrap" style={{ aspectRatio: ratio, cursor: onClick ? 'pointer' : 'default' }} onClick={onClick}>
      {src ? (
        <img src={src} alt={alt} loading="lazy" />
      ) : (
        <div className="placeholder">{placeholder || alt || 'image placeholder'}</div>
      )}
      {overlay > 0 && (
        <div style={{
          position: 'absolute', inset: 0,
          background: `rgba(17,17,17,${overlay})`,
          pointerEvents: 'none',
        }} />
      )}
    </div>
  );
}

/* ----------------- Bronze cursor glow ----------------- */
function CursorGlow({ enabled = true }) {
  const ref = useRef(null);
  useEffect(() => {
    if (!enabled) return;
    const el = ref.current;
    let raf;
    let tx = -200, ty = -200, x = -200, y = -200;
    const onMove = (e) => { tx = e.clientX; ty = e.clientY; if (el) el.classList.add('on'); };
    const onLeave = () => { if (el) el.classList.remove('on'); };
    const tick = () => {
      x += (tx - x) * 0.18;
      y += (ty - y) * 0.18;
      if (el) el.style.transform = `translate(${x}px, ${y}px) translate(-50%, -50%)`;
      raf = requestAnimationFrame(tick);
    };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseleave', onLeave);
    raf = requestAnimationFrame(tick);
    return () => {
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseleave', onLeave);
      cancelAnimationFrame(raf);
    };
  }, [enabled]);
  if (!enabled) return null;
  return <div ref={ref} className="glow-cursor" />;
}

/* ----------------- Lightbox ----------------- */
function Lightbox({ images, index, onClose, onNav }) {
  useEffect(() => {
    if (index == null) return;
    const onKey = (e) => {
      if (e.key === 'Escape') onClose();
      if (e.key === 'ArrowRight') onNav(1);
      if (e.key === 'ArrowLeft') onNav(-1);
    };
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [index, onClose, onNav]);

  if (index == null) return null;
  const img = images[index];
  const isMobile = useIsMobile();

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 200,
      background: 'rgba(17,17,17,0.96)',
      display: 'flex', flexDirection: 'column',
      animation: 'fadeIn 0.4s ease',
    }}>
      <style>{`
        @keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
      `}</style>
      <div style={{
        padding: isMobile ? '20px 18px' : '28px 40px', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
        color: 'rgba(245,240,230,0.75)', gap: 12,
      }}>
        <div className="micro" style={{ color: 'rgba(245,240,230,0.55)' }}>
          {String(index + 1).padStart(2, '0')} <span style={{ color: '#B89A79', margin: '0 8px' }}>/</span> {String(images.length).padStart(2, '0')}
        </div>
        <div className="micro" style={{ color: 'rgba(245,240,230,0.55)' }}>{img.caption}</div>
        <button onClick={onClose} style={{
          background: 'transparent', border: 'none',
          color: 'rgba(245,240,230,0.75)',
          fontFamily: 'Inter', fontSize: 11, letterSpacing: '0.28em',
          textTransform: 'uppercase', cursor: 'pointer',
        }}>Close ✕</button>
      </div>
      <div style={{
        flex: 1, position: 'relative',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        padding: isMobile ? '0 14px 90px' : '0 80px 40px',
      }}>
        <button onClick={() => onNav(-1)} style={navBtn('left', isMobile)}>‹</button>
        <div style={{
          maxWidth: isMobile ? '94vw' : '80vw', maxHeight: '80vh',
          border: '1px solid rgba(184,154,121,0.4)', padding: isMobile ? 6 : 10,
        }}>
          {img.src ? (
            <img src={img.src} alt={img.caption}
              style={{ maxWidth: isMobile ? '90vw' : '78vw', maxHeight: '76vh', display: 'block' }} />
          ) : (
            <div style={{ width: isMobile ? '88vw' : '60vw', height: '70vh' }} className="placeholder">{img.caption}</div>
          )}
        </div>
        <button onClick={() => onNav(1)} style={navBtn('right', isMobile)}>›</button>
      </div>
    </div>
  );
}
function navBtn(side, isMobile) {
  return {
    position: 'absolute',
    [side]: isMobile ? '50%' : 30,
    bottom: isMobile ? 20 : 'auto',
    top: isMobile ? 'auto' : '50%',
    transform: isMobile
      ? `translateX(${side === 'left' ? '-70px' : '10px'})`
      : 'translateY(-50%)',
    width: 54, height: 54, borderRadius: '50%',
    background: isMobile ? 'rgba(17,17,17,0.6)' : 'transparent',
    border: '1px solid rgba(184,154,121,0.5)',
    color: 'rgba(245,240,230,0.85)',
    fontSize: 28, fontFamily: 'EB Garamond, serif',
    cursor: 'pointer',
    transition: 'all 0.4s',
  };
}

/* ----------------- Marquee line ----------------- */
function TickerStrip({ items }) {
  return (
    <div style={{
      borderTop: '1px solid rgba(17,17,17,0.12)',
      borderBottom: '1px solid rgba(17,17,17,0.12)',
      overflow: 'hidden',
      padding: '22px 0',
    }}>
      <div style={{
        display: 'flex', gap: 80, whiteSpace: 'nowrap',
        animation: 'ticker 80s linear infinite',
      }}>
        <style>{`
          @keyframes ticker {
            from { transform: translateX(0) }
            to { transform: translateX(-50%) }
          }
        `}</style>
        {[...items, ...items].map((t, i) => (
          <span key={i} className="micro" style={{
            color: 'rgba(17,17,17,0.55)',
            display: 'inline-flex', alignItems: 'center', gap: 22,
          }}>
            <span style={{ width: 5, height: 5, background: '#B89A79', borderRadius: '50%' }} />
            {t}
          </span>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, {
  useReveal, useIsMobile, Wordmark, Monogram, CTA, Eyebrow, Headline, KBImage, CursorGlow, Lightbox, TickerStrip,
});
