/* global React */
const { useState, useEffect, useRef } = React;
const REDUCED = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

function useCycle(n, ms) {
  const [i, setI] = useState(0);
  useEffect(() => {
    if (REDUCED || n < 2) return;
    const t = setInterval(() => setI((v) => (v + 1) % n), ms);
    return () => clearInterval(t);
  }, [n, ms]);
  return i;
}

function Counter({ to, suffix }) {
  const ref = useRef(null);
  const [val, setVal] = useState(REDUCED ? to : 0);
  useEffect(() => {
    if (REDUCED) return;
    let started = false;
    const io = new IntersectionObserver((es) => {
      es.forEach((e) => {
        if (e.isIntersecting && !started) {
          started = true;
          const start = performance.now();
          const tick = (now) => {
            const t = Math.min(1, (now - start) / 1400);
            setVal(Math.round((1 - Math.pow(1 - t, 3)) * to));
            if (t < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
          io.disconnect();
        }
      });
    }, { threshold: 0.5 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, [to]);
  return <span ref={ref}>{val}{suffix}</span>;
}

function Metric({ value, label }) {
  const m = !value.includes('–') && value.match(/^(\d+)(.*)$/);
  return (
    <div className="metric">
      <div className="metric-num">{m ? <Counter to={+m[1]} suffix={m[2]} /> : value}</div>
      <div className="metric-label">{label}</div>
    </div>);
}

/* ===== BMW poster carousel ===== */
function PosterCarousel({ posters }) {
  const n = posters.length;
  const [i, setI] = useState(0);
  const [dx, setDx] = useState(0);
  const drag = useRef(null);
  const go = (k) => setI(((k % n) + n) % n);
  const onDown = (e) => { drag.current = { x: e.clientX, moved: false }; };
  const onMove = (e) => {
    if (!drag.current) return;
    const d = e.clientX - drag.current.x;
    if (Math.abs(d) > 4) drag.current.moved = true;
    setDx(d);
  };
  const onUp = () => {
    if (!drag.current) return;
    if (dx < -60) go(i + 1); else if (dx > 60) go(i - 1);
    drag.current = null;
    setDx(0);
  };
  const onKey = (e) => {
    if (e.key === 'ArrowRight') { e.preventDefault(); go(i + 1); }
    if (e.key === 'ArrowLeft') { e.preventDefault(); go(i - 1); }
  };
  return (
    <div className="pcar rv" tabIndex={0} onKeyDown={onKey} aria-label="Campaign posters. Use arrow keys to browse">
      <div
        className={`pcar-stage ${drag.current ? 'dragging' : ''}`}
        onPointerDown={onDown} onPointerMove={onMove} onPointerUp={onUp} onPointerLeave={onUp}>
        <div className="pcar-track" style={{ transform: `translateX(calc(-0.5 * var(--cw) - ${i} * (var(--cw) + var(--cgap)) + ${dx}px))` }}>
          {posters.map((p, k) =>
          <figure className={`pcar-card ${k === i ? 'active' : ''}`} key={k} onClick={() => { if (!drag.current || !drag.current.moved) go(k); }}>
            <img src={p.src} alt={`Keep It Perfect poster: ${p.caption}`} draggable="false" loading="lazy" />
          </figure>)}
        </div>
      </div>
      <div className="pcar-bar">
        <span className="pcar-count"><b>{String(i + 1).padStart(2, '0')}</b> / {String(n).padStart(2, '0')}</span>
        <span className="pcar-cap">{posters[i].caption}</span>
        <span className="pcar-navs">
          <button className="pcar-nav" onClick={() => go(i - 1)} aria-label="Previous poster">← Prev</button>
          <button className="pcar-nav" onClick={() => go(i + 1)} aria-label="Next poster">Next →</button>
        </span>
      </div>
    </div>);
}

/* ===== BMW film stage ===== */
function FilmStage({ videos, note }) {
  const [loud, setLoud] = React.useState(-1);
  const refs = React.useRef([]);
  const toggle = (i) => {
    const next = loud === i ? -1 : i;
    setLoud(next);
    refs.current.forEach((v, j) => {
      if (!v) return;
      v.muted = j !== next;
      if (j !== next) return;
      v.volume = 1;
      if (!v.paused) return;
      const p = v.play();
      if (p && p.catch) p.catch((e) => { if (e && e.name !== 'NotAllowedError') return; v.muted = true; setLoud((c) => (c === j ? -1 : c)); v.play().catch(() => {}); });
    });
  };
  return (
    <div className="film-stage">
      <div className="film-stage-head rv">
        <span className="step-label">The film</span>
        <p className="film-stage-note">{note}</p>
      </div>
      <div className="film-stage-inner rv">
        {videos.map((v, i) =>
        <div className="film-clip" key={i}>
          <video ref={(el) => { refs.current[i] = el; }} src={v} autoPlay muted loop playsInline onClick={() => toggle(i)} title={loud === i ? 'Click to mute' : 'Click for sound'}></video>
          <button className="film-sound" onClick={() => toggle(i)} aria-label={loud === i ? 'Mute clip' : 'Play sound'}>{loud === i ? '♪ Sound on' : '♪ Sound off'}</button>
        </div>)}
      </div>
    </div>);
}

/* (Ficus system canvas lives in ficus-canvas.jsx) */

Object.assign(window, { REDUCED, useCycle, Counter, Metric, PosterCarousel, FilmStage });
