---
/**
 * DemoVideo — the multiplayer demo centerpiece.
 *
 * Poster-first and lazy (`preload="none"`); never autoplays in markup. A tiny
 * IntersectionObserver (bound on astro:page-load, see <script> below) plays it
 * when scrolled into view ONLY if the user hasn't asked for reduced motion —
 * otherwise the static poster + manual play control stays.
 *
 * Until the real files exist, pass no `mp4`/`webm` and it renders a Placeholder.
 */
import Placeholder from './Placeholder.astro';
import Icon from './Icon.astro';

interface Props {
  mp4?: string; // e.g. "/video/multiplayer-demo.mp4"
  webm?: string;
  poster?: string;
  caption?: string;
  ratio?: string; // default 16/9
  /** When true and no video yet, show a big "coming soon" panel instead of
   *  the internal PRODUCE placeholder. */
  comingSoon?: boolean;
  /** Panel text for the comingSoon state. */
  soonLabel?: string;
  class?: string;
}

const {
  mp4,
  webm,
  poster,
  caption,
  ratio = '16 / 9',
  comingSoon = false,
  soonLabel = 'Demo coming soon',
  class: cls = '',
} = Astro.props;
const hasVideo = Boolean(mp4 || webm);
---

<figure class={`demo ${cls}`}>
  {
    hasVideo ? (
      <div class="demo-frame" data-demo-video style={`aspect-ratio:${ratio};`}>
        <video
          poster={poster}
          preload="none"
          muted
          loop
          playsinline
          controls
          aria-label={caption ?? 'PCBJam multiplayer editing demo'}
        >
          {webm && <source src={webm} type="video/webm" />}
          {mp4 && <source src={mp4} type="video/mp4" />}
        </video>
        <button class="demo-play" type="button" aria-label="Play demo" data-demo-play>
          <Icon name="icons/play.svg" size="3.5rem" alt="" />
        </button>
      </div>
    ) : comingSoon ? (
      <div class="demo-soon bp-grid" style={`aspect-ratio:${ratio};`}>
        <span class="demo-soon-text">{soonLabel}</span>
      </div>
    ) : (
      <Placeholder
        label="PRODUCE: multiplayer demo loop — 2–3 live cursors, one board (§4b.2)"
        kind="video"
        ratio={ratio}
      />
    )
  }
  {caption && <figcaption class="demo-caption">{caption}</figcaption>}
</figure>

<style>
  .demo {
    margin: 0;
  }
  .demo-frame {
    position: relative;
    width: 100%;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--bg-soft);
  }
  .demo-frame video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .demo-play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    border: 0;
    /* Fixed dark scrim (not --bg-derived): white glyph over video needs a dark
       veil in both themes. */
    background: rgba(11, 16, 32, 0.35);
    color: #fff;
    cursor: pointer;
  }
  .demo-play[hidden] {
    display: none;
  }
  .demo-soon {
    display: grid;
    place-items: center;
    width: 100%;
    padding: 1.5rem;
    text-align: center;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background-color: var(--bg-soft);
  }
  .demo-soon-text {
    font-size: clamp(1.1rem, 3vw, 1.75rem);
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--fg);
  }
  .demo-caption {
    margin-top: 0.75rem;
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--fg-muted);
    text-align: center;
  }
</style>

<script>
  // Bound on every load + SPA swap (ClientRouter re-runs astro:page-load).
  function initDemoVideos() {
    const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    document.querySelectorAll<HTMLElement>('[data-demo-video]').forEach((frame) => {
      if (frame.dataset.bound === '1') return;
      frame.dataset.bound = '1';
      const video = frame.querySelector('video');
      const playBtn = frame.querySelector<HTMLButtonElement>('[data-demo-play]');
      if (!video) return;

      playBtn?.addEventListener('click', () => {
        video.play();
        playBtn.hidden = true;
      });
      video.addEventListener('play', () => {
        if (playBtn) playBtn.hidden = true;
      });

      if (reduce || !('IntersectionObserver' in window)) return; // poster + manual play only

      const io = new IntersectionObserver(
        (entries) => {
          for (const e of entries) {
            if (e.isIntersecting) video.play().catch(() => {});
            else video.pause();
          }
        },
        { threshold: 0.5 },
      );
      io.observe(frame);
    });
  }
  document.addEventListener('astro:page-load', initDemoVideos);
</script>
