// Browser-only. Inlined into built HTML by inject-transition.js.
// Sets up a keydown interceptor that dispatches registered custom transitions.
;(function () {
  const _factories = {}

  window.__transitions = {
    register(name, factory) {
      _factories[name] = factory
    },
  }

  const FORWARD = new Set([' ', 'ArrowRight', 'ArrowDown', 'PageDown', 'Enter'])
  const BACKWARD = new Set(['ArrowLeft', 'ArrowUp', 'PageUp'])

  function activeSlide() {
    return document.querySelector('svg[data-marpit-svg].bespoke-marp-active')
  }

  function allSlides() {
    return Array.from(document.querySelectorAll('svg[data-marpit-svg]'))
  }

  let _current = null

  document.addEventListener('keydown', function (e) {
    const forward = FORWARD.has(e.key)
    const backward = BACKWARD.has(e.key)
    if (!forward && !backward) return

    const from = activeSlide()
    if (!from) return

    const section = from.querySelector('section')
    if (!section) return

    const raw = forward ? section.dataset.transition : section.dataset.transitionBack
    if (!raw) return

    let parsed
    try { parsed = JSON.parse(raw) } catch { return }

    const factory = _factories[parsed.name]
    if (!factory) return

    const slides = allSlides()
    const idx = slides.indexOf(from)
    const to = forward ? slides[idx + 1] : slides[idx - 1]
    if (!to) return

    if (_current) { _current.cancel(); _current = null }
    const duration = parsed.duration ?? 500
    const transition = factory(from, to, duration)
    // Set _current immediately so a second keypress during the rAF gap can cancel this transition.
    _current = transition
    transition.capture()

    // Let Marp's bubble-phase listener navigate (updates deck state, URL hash).
    // play() runs after Marp has switched the active slide.
    requestAnimationFrame(() => {
      if (_current !== transition) return  // superseded by a newer keypress
      transition.play()
    })
  }, { capture: true })
})()
