const app = Elm.Main.init({ flags: window.__FLAGS__ })

// Handle smoothly scrolling to links
const scrollToHash = () => {
  const BREAKPOINT_XL = 1920
  const NAVBAR_HEIGHT_PX = window.innerWidth > BREAKPOINT_XL ? 127 : 102
  const element = window.location.hash && document.querySelector(window.location.hash)
  if (element) {
    // element.scrollIntoView({ behavior: 'smooth' })
    window.scroll({ behavior: 'smooth', top: window.pageYOffset + element.getBoundingClientRect().top - NAVBAR_HEIGHT_PX })
  } else {
    window.scroll({ behavior: 'smooth', top: 0 })
  }
}

app.ports.onUrlChange.subscribe(_ => setTimeout(scrollToHash, 400))
setTimeout(scrollToHash, 400)

// Quick search shortcut (/)
window.addEventListener('keypress', (e) => {
  if (e.key === '/') {
    const el = document.getElementById('quick-search')
    if (el && el !== document.activeElement) {
      el.focus()
      el.select()
      e.preventDefault()
    }
  }
  return false
})

// HighlightJS custom element
customElements.define('prism-js', class HighlightJS extends HTMLElement {
  constructor() { super() }
  connectedCallback() {
    const pre = document.createElement('pre')

    pre.className = this.language ? `language-${this.language}` : `language-elm`
    pre.textContent = this.body

    this.appendChild(pre)
    window.Prism.highlightElement(pre)
  }
})

// Dropdown arrow key support
customElements.define('dropdown-arrow-keys', class DropdownArrowKeys extends HTMLElement {
  constructor() {
    super()
  }
  connectedCallback() {
    const component = this
    const arrows = { ArrowUp: -1, ArrowDown: 1 }
    const interactiveChildren = () => component.querySelectorAll('input, a, button')

    const onBlur = (e) => window.requestAnimationFrame(_ => {
      const active = document.activeElement
      const siblings = interactiveChildren()
      let foundFocusedSibling = false

      e.target.removeEventListener('blur', onBlur)

      siblings.forEach(sibling => {
        if (sibling === active) {
          sibling.addEventListener('blur', onBlur)
          foundFocusedSibling = true
        }
      })
      if (foundFocusedSibling === false) {
        component.dispatchEvent(new CustomEvent('clearDropdown'))
        siblings.forEach(el => el.addEventListener('focus', _ => el.addEventListener('blur', onBlur)))
      }
    })

    interactiveChildren().forEach(el => el.addEventListener('blur', onBlur))

    component.addEventListener('keydown', (e) => {
      const delta = arrows[e.key]
      if (delta) {
        e.preventDefault()
        const interactive = interactiveChildren()
        const count = interactive.length
        const active = document.activeElement
        if (count < 2) return

        interactive.forEach((el, i) => {
          if (active == el) {
            const next = interactive[(i + delta + count) % count]
            next.focus()
          }
        })
      }
    })
  }
})

window.addEventListener('keyup', (e) => {
  const el = document.getElementById('quick-search')
  if (e.key === 'Escape' && el === document.activeElement) {
    if (el) el.blur()
  }
})