<slot></slot>
<script>
  import { virtualListStore } from './virtualListStore'
  import throttle from 'lodash/throttle'
  import { isFullscreen, attachFullscreenListener, detachFullscreenListener } from '../../_utils/fullscreen'
  import { mark, stop } from '../../_utils/marks'
  import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
  import { isMobile } from '../../_utils/isMobile'

  const SCROLL_EVENT_DELAY = 300

  export default {
    oncreate() {
      mark('onCreate VirtualListContainer')
      this.store.setCurrentRealm(this.get('realm'))
      let node = document.querySelector(this.get('containerQuery'))
      this.setupScroll(node)
      this.setupFullscreen()
      let scrollTop = this.store.get('scrollTop')
      if (scrollTop > 0) {
        this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
          console.log('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight)
          if (!this.get('initializedScrollTop') && allVisibleItemsHaveHeight && node) {
            this.set({'initializedScrollTop': true})
            mark('set scrollTop')
            console.log('forcing scroll top to ', scrollTop)
            node.scrollTop = scrollTop
            stop('set scrollTop')
          }
        })
      } else {
        this.store.setForRealm({
          scrollHeight: node.scrollHeight,
          offsetHeight: node.offsetHeight
        })
      }
      stop('onCreate VirtualListContainer')
    },
    ondestroy() {
      this.teardownScroll()
      this.teardownFullscreen()
      this.store.setCurrentRealm(null)
    },
    store: () => virtualListStore,
    methods: {
      setupScroll(node) {
        if (!node) {
          return
        }
        this.scrollListener = throttle(event => {
          if (this.get('fullscreen')) {
            return
          }
          this.onScroll(event)
        }, SCROLL_EVENT_DELAY, {
          leading: true,
          trailing: true
        })
        node.addEventListener('scroll', this.scrollListener)
      },
      teardownScroll() {
        let node = document.querySelector(this.get('containerQuery'))
        if (node) {
          node.removeEventListener('scroll', this.scrollListener)
        }
      },
      setupFullscreen() {
        this.onFullscreenChange = this.onFullscreenChange.bind(this)
        attachFullscreenListener(this.onFullscreenChange)
      },
      teardownFullscreen() {
        detachFullscreenListener(this.onFullscreenChange)
      },
      onScroll(event) {
        let { scrollTop, scrollHeight } = event.target

        // On mobile devices, this can make scrolling more responsive. On
        // desktop browsers... it's probably overkill, and can lead to a
        // checkerboarding issue ("I just scrolled, why is it blank for 5 seconds?").
        let runTask = isMobile() ? scheduleIdleTask : requestAnimationFrame

        runTask(() => {
          mark('onScroll -> setForRealm()')
          this.store.setForRealm({scrollTop, scrollHeight})
          stop('onScroll -> setForRealm()')
        })
      },
      onFullscreenChange() {
        mark('onFullscreenChange')
        console.log('is fullscreen? ', isFullscreen())
        this.set({ fullscreen: isFullscreen() })
        stop('onFullscreenChange')
      }
    },
    computed: {
      // TODO: bug in svelte/store – the observer in oncreate() never get removed without this hack
      allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight
    }
  };
</script>