// skills-masonry-sequence.jsx — StringTune masonry + sequence (skills/tutorial-02-masonry-orchestrated, tutorial-16-sequence)

const Reveal = window.Reveal || function RevealPassthrough({ children }) {
  return <>{children}</>;
};

function stPrefersReducedMotion() {
  return typeof window !== 'undefined' &&
    window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}

const ST_SEQ_ID = 'pfSeq';
const ST_MASONRY_ID = 'outcomes';

function emitMasonryUpdate(payload = {}) {
  try {
    const st = window.StringTune?.StringTune?.getInstance?.();
    st?.emit?.(`masonry:update:${ST_MASONRY_ID}`, payload);
  } catch (_) { /* noop */ }
}

const MASONRY_FIXED_MS = 1100;
const MASONRY_RANDOM_MIN = 1100;
const MASONRY_RANDOM_MAX = 2800;
function randomMasonryMs() {
  return String(Math.floor(Math.random() * (MASONRY_RANDOM_MAX - MASONRY_RANDOM_MIN + 1)) + MASONRY_RANDOM_MIN);
}

const MASONRY_COL_OPTIONS = [3, 4, 5, 6, 7, 8];

/** Toggle between PNG and WebP for the same basename when one fails to load. */
function showcaseAltExt(path) {
  const p = path.split('?')[0];
  if (/\.png$/i.test(p)) return p.replace(/\.png$/i, '.webp');
  if (/\.webp$/i.test(p)) return p.replace(/\.webp$/i, '.png');
  return p;
}

function imgShowcaseFallback(ev) {
  const el = ev.currentTarget;
  if (el.dataset._fb === '1') return;
  el.dataset._fb = '1';
  const cur = (el.getAttribute('src') || '').split('?')[0];
  const next = showcaseAltExt(cur);
  if (next !== cur) el.src = next;
}

const StTuneSequenceBand = () => {
  const rootRef = React.useRef(null);
  const prevRef = React.useRef(null);
  const nextRef = React.useRef(null);
  const dotRefs = React.useRef([]);
  const figRefs = React.useRef([]);
  const imgRefs = React.useRef([]);

  const slides = React.useMemo(() => [
    {
      id: 'slide-agent-knowledge',
      src: 'showcase/01-agent-knowledge.png',
      title: 'Agent + knowledge',
      sub: 'Create Agent with Knowledge — PDF, URL, text, and vector paths merged into tools and webhook response.',
    },
    {
      id: 'slide-content-post',
      src: 'showcase/02-content-post-automation.png',
      title: 'Content & post automation',
      sub: 'Make.com — route image vs video, poll generation HTTP, publish to Meta & Instagram, log to Airtable.',
    },
    {
      id: 'slide-orchestration',
      src: 'showcase/03-orchestration-workflow.png',
      title: 'Omnichannel orchestration',
      sub: 'n8n — WhatsApp, Telegram, Gmail, webhooks → route by type → Gemini & AI agent → reply.',
    },
    {
      id: 'slide-maps-lead',
      src: 'showcase/04-maps-lead-gen.png',
      title: 'Maps lead generation',
      sub: 'Google Places API v1 — paginated search, enrichment, optional scrape, CSV out.',
    },
  ], []);

  React.useEffect(() => {
    if (stPrefersReducedMotion()) return;
    const S = ST_SEQ_ID;
    const root = rootRef.current;
    if (root) {
      root.setAttribute('string', 'sequence');
      root.setAttribute('string-entering-duration', `${S}[60]`);
      root.setAttribute('string-leaving-duration', `${S}[720]`);
      root.setAttribute('string-active-step', `${S}[0]`);
    }
    prevRef.current?.setAttribute('string', 'sequence');
    prevRef.current?.setAttribute('string-sequence-trigger', `${S}[prev|loop]`);
    nextRef.current?.setAttribute('string', 'sequence');
    nextRef.current?.setAttribute('string-sequence-trigger', `${S}[next|loop]`);
    slides.forEach((_, i) => {
      const fig = figRefs.current[i];
      if (fig) {
        fig.setAttribute('string', 'sequence');
        fig.setAttribute('string-sequence', `${S}[${i}]`);
      }
      const dot = dotRefs.current[i];
      if (dot) {
        dot.setAttribute('string', 'sequence');
        dot.setAttribute('string-sequence-trigger', `${S}[${i}]`);
      }
    });
  }, [slides]);

  if (stPrefersReducedMotion()) {
    const s = slides[0];
    return (
      <section className="section st-seq-section" id="proof" aria-labelledby="st-seq-heading">
        <Reveal><div className="sec-label"><span className="sec-num">03½</span><span className="sec-line" /><span className="sec-name">Proof</span></div></Reveal>
        <Reveal delay={80}><h2 id="st-seq-heading" className="sec-h">Production workflows, not mockups.</h2></Reveal>
        <Reveal delay={120}><p className="sec-sub">Step through real builds — reduced motion shows the first frame only.</p></Reveal>
        <div className="st-seq-shell st-seq-shell--static">
          <figure className="st-seq-figure st-seq-figure--static -active">
            <img src={s.src} onError={imgShowcaseFallback} alt={`${s.title} — workflow screenshot`} loading="lazy" />
          </figure>
          <ul className="st-seq-legend">
            {slides.map((sl) => (
              <li key={sl.id}><strong>{sl.title}</strong><span>{sl.sub}</span></li>
            ))}
          </ul>
        </div>
      </section>
    );
  }

  return (
    <section className="section st-seq-section" id="proof" aria-labelledby="st-seq-heading">
      <Reveal><div className="sec-label"><span className="sec-num">03½</span><span className="sec-line" /><span className="sec-name">Proof</span></div></Reveal>
      <Reveal delay={80}><h2 id="st-seq-heading" className="sec-h">Production workflows, not mockups.</h2></Reveal>
      <Reveal delay={120}><p className="sec-sub">Screenshots from shipped automation — same sequence motion as tutorial-16-sequence.</p></Reveal>

      <Reveal delay={160} y={24}>
        <div className="st-seq-shell">
          <nav className="st-seq-arrows" aria-label="Carousel">
            <button type="button" ref={prevRef} className="st-seq-arrow" aria-label="Previous slide">&larr;</button>
            <button type="button" ref={nextRef} className="st-seq-arrow" aria-label="Next slide">&rarr;</button>
          </nav>

          <div ref={rootRef} className="st-sequence">
            {slides.map((s, i) => (
              <figure
                key={s.id}
                className="st-seq-figure"
                ref={(el) => { figRefs.current[i] = el; }}
              >
                <img
                  ref={(el) => { imgRefs.current[i] = el; }}
                  src={s.src}
                  onError={imgShowcaseFallback}
                  alt={`${s.title} — workflow screenshot`}
                  decoding="async"
                  loading="lazy"
                />
              </figure>
            ))}
          </div>

          <nav className="st-seq-dots" aria-label="Slides">
            {slides.map((s, i) => (
              <button
                key={s.id}
                type="button"
                ref={(el) => { dotRefs.current[i] = el; }}
                className="st-seq-dot"
                aria-label={`Show slide ${i + 1}: ${s.title}`}
              >
                {i + 1}
              </button>
            ))}
          </nav>

          <ul className="st-seq-legend">
            {slides.map((sl) => (
              <li key={sl.id}><strong>{sl.title}</strong><span>{sl.sub}</span></li>
            ))}
          </ul>
        </div>
      </Reveal>
    </section>
  );
};

const StTuneMasonrySection = () => {
  const gridRef = React.useRef(null);
  const itemRefs = React.useRef([]);
  const [cols, setCols] = React.useState(3);
  const [mode, setMode] = React.useState('manual');
  const [randomTiming, setRandomTiming] = React.useState(false);

  const tiles = React.useMemo(() => [
    { id: 'mz01', src: 'showcase/01-agent-knowledge.png', label: 'Agent + knowledge' },
    { id: 'mz02', src: 'showcase/02-content-post-automation.png', label: 'Content & post automation' },
    { id: 'mz03', src: 'showcase/03-orchestration-workflow.png', label: 'Omnichannel orchestration' },
    { id: 'mz04', src: 'showcase/04-maps-lead-gen.png', label: 'Maps lead generation' },
    { id: 'mz05', src: 'showcase/03-orchestration-workflow.png', label: 'Route by message type' },
    { id: 'mz06', src: 'showcase/01-agent-knowledge.png', label: 'PDF · URL · vector ingest' },
    { id: 'mz07', src: 'showcase/02-content-post-automation.png', label: 'Video vs image router' },
    { id: 'mz08', src: 'showcase/04-maps-lead-gen.png', label: 'Places API · scrape · CSV' },
    { id: 'mz09', src: 'showcase/03-orchestration-workflow.png', label: 'AI assistant + tools' },
  ], []);

  const applyItemTiming = React.useCallback(() => {
    tiles.forEach((_, i) => {
      const el = itemRefs.current[i];
      if (!el) return;
      const ms = randomTiming ? randomMasonryMs() : String(MASONRY_FIXED_MS);
      el.setAttribute('string-masonry-position-time', ms);
      el.setAttribute('string-masonry-size-time', ms);
      el.setAttribute('string-masonry-position-easing', 'cubic-bezier(0.69, 0, 0, 1)');
      el.setAttribute('string-masonry-size-easing', 'cubic-bezier(0.69, 0, 0, 1)');
    });
  }, [tiles, randomTiming]);

  React.useEffect(() => {
    if (stPrefersReducedMotion()) return;
    const grid = gridRef.current;
    if (!grid) return;
    grid.setAttribute('string-id', ST_MASONRY_ID);
    grid.setAttribute('string', 'masonry');
    grid.setAttribute('string-masonry-cols', `1|480:2|768:${cols}|1024:${cols}|1280:${cols}`);
    grid.setAttribute('string-masonry-gap', '10|640:12|1024:16|1280:18');
    grid.setAttribute('string-masonry-mode', mode);

    applyItemTiming();

    emitMasonryUpdate({ cols, mode });
    const delayed = [80, 400, 1200].map((ms) =>
      setTimeout(() => emitMasonryUpdate({ cols, mode }), ms));
    return () => delayed.forEach(clearTimeout);
  }, [tiles, cols, mode, randomTiming, applyItemTiming]);

  React.useEffect(() => {
    if (stPrefersReducedMotion()) return;
    const onResize = () => emitMasonryUpdate({ cols, mode });
    window.addEventListener('resize', onResize, { passive: true });
    return () => window.removeEventListener('resize', onResize);
  }, [cols, mode]);

  if (stPrefersReducedMotion()) {
    return (
      <section className="section st-masonry-section" id="gallery" aria-labelledby="st-masonry-heading">
        <Reveal><div className="sec-label"><span className="sec-num">06½</span><span className="sec-line" /><span className="sec-name">Gallery</span></div></Reveal>
        <Reveal delay={80}><h2 id="st-masonry-heading" className="sec-h">Delivery snapshots — masonry layout.</h2></Reveal>
        <Reveal delay={120}><p className="sec-sub">Workflow screenshots (WebP); simplified columns when reduced motion is on.</p></Reveal>
        <div className="st-masonry-fallback">
          {tiles.map((t) => (
            <article key={t.id} className="st-masonry-item st-masonry-item--static">
              <figure>
                <img src={t.src} onError={imgShowcaseFallback} alt="" loading="lazy" />
              </figure>
              <span className="st-masonry-cap">{t.label}</span>
            </article>
          ))}
        </div>
      </section>
    );
  }

  return (
    <section className="section st-masonry-section" id="gallery" aria-labelledby="st-masonry-heading">
      <Reveal><div className="sec-label"><span className="sec-num">06½</span><span className="sec-line" /><span className="sec-name">Gallery</span></div></Reveal>
      <Reveal delay={80}><h2 id="st-masonry-heading" className="sec-h">Delivery snapshots — orchestrated masonry.</h2></Reveal>
      <Reveal delay={120}><p className="sec-sub">Same StringTune masonry as tutorial-02-masonry-orchestrated — tune columns, mode, and animation timing below.</p></Reveal>

      <nav className="st-masonry-controls" aria-label="Masonry layout">
        <div className="st-control-group">
          <span className="st-control-label">Columns</span>
          <div className="st-button-group" role="group">
            {MASONRY_COL_OPTIONS.map((n) => (
              <button
                key={n}
                type="button"
                className={`st-control-btn ${cols === n ? '-active' : ''} ${n >= 6 ? 'st-control-btn--wide-only' : ''}`}
                onClick={() => setCols(n)}
              >
                {n}
              </button>
            ))}
          </div>
        </div>
        <div className="st-control-group">
          <span className="st-control-label">Mode</span>
          <div className="st-button-group" role="group">
            <button
              type="button"
              className={`st-control-btn ${mode === 'auto' ? '-active' : ''}`}
              onClick={() => setMode('auto')}
            >
              Auto
            </button>
            <button
              type="button"
              className={`st-control-btn ${mode === 'manual' ? '-active' : ''}`}
              onClick={() => setMode('manual')}
            >
              Manual
            </button>
          </div>
        </div>
        <div className="st-control-group">
          <span className="st-control-label">Timing</span>
          <div className="st-timing-row">
            <label className="st-timing-switch">
              <input
                type="checkbox"
                checked={randomTiming}
                onChange={(e) => setRandomTiming(e.target.checked)}
                aria-describedby="st-timing-hint"
              />
              <span className="st-timing-slider" aria-hidden />
            </label>
            <span id="st-timing-hint" className={`st-timing-label ${randomTiming ? '-on' : ''}`}>Random</span>
          </div>
        </div>
      </nav>

      <Reveal delay={160} y={24}>
        <div ref={gridRef} className="st-masonry-grid">
          {tiles.map((t, i) => (
            <div
              key={t.id}
              className="st-masonry-item"
              ref={(el) => { itemRefs.current[i] = el; }}
            >
              <figure>
                <img
                  src={t.src}
                  onError={imgShowcaseFallback}
                  alt=""
                  decoding="async"
                  loading="lazy"
                />
              </figure>
              <span className="st-masonry-cap">{t.label}</span>
            </div>
          ))}
        </div>
      </Reveal>
    </section>
  );
};

window.StTuneSequenceBand = StTuneSequenceBand;
window.StTuneMasonrySection = StTuneMasonrySection;
