// hifi-components.jsx — shared UI atoms for the hi-fi La Foire page.
// Exports on window for cross-script use.

const { useEffect, useRef, useState } = React;

// ─── Tagline JOUER ◆ TRINQUER ◆ MANGER ───────────────────────
function Tagline({ size = 14, className = '', style = {} }) {
  return (
    <span className={`tagline ${className}`} style={{ fontSize: size, ...style }}>
      <span>Jouer</span>
      <span className="tagline__dot">◆</span>
      <span>Trinquer</span>
      <span className="tagline__dot">◆</span>
      <span>Manger</span>
    </span>
  );
}

// ─── Ribbon défilant (sticky bandeau top) ────────────────────
function StickyRibbon() {
  // Construit un long ruban : 12 copies de la tagline → scroll infini
  const items = Array.from({ length: 12 }).map((_, i) => (
    <span className="ribbon__item" key={i}>
      Jouer&nbsp;&nbsp;Trinquer&nbsp;&nbsp;Manger
    </span>
  ));
  return (
    <div className="ribbon" aria-hidden="true">
      <div className="ribbon__track">
        {items}{items}
      </div>
    </div>
  );
}

// ─── Nav ─────────────────────────────────────────────────────
function Nav() {
  const { links, cta } = CONTENT.nav;
  return (
    <nav className="nav container">
      <a href="#" className="nav__logo" aria-label="Au Taquet — La Foire">
        <img src="assets/logo-red-diamond.png" alt="Au Taquet" />
      </a>
      <div className="nav__links">
        {links.map(l => <a key={l.href} href={l.href}>{l.label}</a>)}
      </div>
      <a href="#tally-open=D4ZNBp&tally-emoji-text=👋&tally-emoji-animation=tada&tally-auto-close=1000" className="btn btn--losange btn--sm btn--yellow nav__cta">
        {cta}
      </a>
      <button className="nav__burger" aria-label="Menu">≡</button>
    </nav>
  );
}

// ─── NumberDiamond ───────────────────────────────────────────
function NumDiamond({ children, variant = '', size = 'md', rotate, className = '', style = {} }) {
  const sizeCls = { md: '', lg: 'numdiamond--lg', xl: 'numdiamond--xl' }[size] || '';
  const variantCls = variant ? `numdiamond--${variant}` : '';
  return (
    <span
      className={`numdiamond ${sizeCls} ${variantCls} ${className}`}
      style={{ transform: rotate != null ? `rotate(${rotate}deg)` : undefined, ...style }}
    >
      {children}
    </span>
  );
}

// ─── Bulb garland (guirlande lampions animée) ────────────────
function BulbGarland({ count = 8 }) {
  return (
    <div className="bulb-garland" aria-hidden="true">
      {Array.from({ length: count }).map((_, i) => <span key={i} className="bulb" />)}
    </div>
  );
}

// ─── Starburst (rayons rotation lente derrière hero) ─────────
function Starburst({ color = '#F4BF33' }) {
  // 24 rayons en triangle
  const rays = Array.from({ length: 24 }, (_, i) => {
    const angle = (360 / 24) * i;
    const next  = (360 / 24) * (i + 0.5);
    const x1 = 800 + Math.cos(angle * Math.PI / 180) * 800;
    const y1 = 800 + Math.sin(angle * Math.PI / 180) * 800;
    const x2 = 800 + Math.cos(next * Math.PI / 180) * 250;
    const y2 = 800 + Math.sin(next * Math.PI / 180) * 250;
    return `M ${x1} ${y1} L ${x2} ${y2} L 800 800 Z`;
  });
  return (
    <div className="starburst" aria-hidden="true">
      <svg viewBox="0 0 1600 1600" xmlns="http://www.w3.org/2000/svg">
        {rays.map((d, i) => (
          <path key={i} d={d} fill={color} opacity={i % 2 ? 0.85 : 0.4} />
        ))}
      </svg>
    </div>
  );
}

// ─── Kraft overlay subtil ────────────────────────────────────
function KraftOverlay() {
  return <div className="kraft" aria-hidden="true" />;
}

// ─── Damier band ─────────────────────────────────────────────
function Damier({ variant = '' }) {
  return <div className={`damier ${variant ? 'damier--' + variant : ''}`} aria-hidden="true" />;
}

// ─── Eyebrow (sur-titre small caps + barres) ─────────────────
function Eyebrow({ children }) {
  return <div className="section__eyebrow">{children}</div>;
}

// ─── Reveal-on-scroll wrapper (IntersectionObserver) ─────────
function Reveal({ children, as: As = 'div', delay = 0, className = '', ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    if (typeof IntersectionObserver === 'undefined') { setShown(true); return; }
    const obs = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        setTimeout(() => setShown(true), delay);
        obs.disconnect();
      }
    }, { threshold: 0.15 });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, [delay]);
  return (
    <As ref={ref} className={`reveal ${shown ? 'is-in' : ''} ${className}`} {...rest}>
      {children}
    </As>
  );
}

// ─── Animated counter (compte un nombre quand visible) ───────
function CountUp({ end, suffix = '', duration = 1400, format = (v) => v }) {
  const [val, setVal] = useState(0);
  const ref = useRef(null);
  const started = useRef(false);
  useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting && !started.current) {
        started.current = true;
        const start = performance.now();
        const tick = (now) => {
          const t = Math.min(1, (now - start) / duration);
          const eased = 1 - Math.pow(1 - t, 3);
          setVal(Math.round(end * eased));
          if (t < 1) requestAnimationFrame(tick);
        };
        requestAnimationFrame(tick);
        obs.disconnect();
      }
    }, { threshold: 0.4 });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, [end, duration]);
  return <span ref={ref}>{format(val)}{suffix}</span>;
}

// Stand data — source of truth is now content.js
const STANDS_DATA = CONTENT.stands.items;

// Expose
Object.assign(window, {
  Tagline, StickyRibbon, Nav, NumDiamond, BulbGarland, Starburst,
  KraftOverlay, Damier, Eyebrow, Reveal, CountUp,
  STANDS_DATA,
});
