<!-- TODO: setting height is hacky, just make this element the scroller -->
<div class="virtual-list {{shown ? '' : 'hidden'}}" style="height: {{$height}}px;">
  {{#if $visibleItems}}
    {{#each $visibleItems as visibleItem @key}}
      <VirtualListLazyItem :component
                           offset="{{visibleItem.offset}}"
                           makeProps="{{makeProps}}"
                           key="{{visibleItem.key}}"
                           index="{{visibleItem.index}}"
      />
    {{/each}}
  {{/if}}
  {{#if $showFooter}}
    <VirtualListFooter component="{{footerComponent}}"/>
  {{/if}}
</div>
<style>
  .virtual-list {
    position: relative;
    transition: opacity 0.25s linear;
  }
</style>
<script>
  import VirtualListLazyItem from './VirtualListLazyItem'
  import VirtualListFooter from './VirtualListFooter.html'
  import { virtualListStore } from './virtualListStore'
  import throttle from 'lodash/throttle'
  import { mark, stop } from '../../_utils/marks'

  const DISTANCE_FROM_BOTTOM_TO_FIRE = 400
  const SCROLL_TO_BOTTOM_DELAY = 1000

  export default {
    oncreate () {
      this.observe('showFooter', showFooter => {
        this.store.setForRealm({showFooter: showFooter})
      })
      this.observe('items', (items) => {
        mark('set items')
        this.store.setForRealm({items: items})
        stop('set items')
        this.fireScrollToBottom = throttle(() => {
          this.fire('scrollToBottom')
        }, SCROLL_TO_BOTTOM_DELAY)
      })

      this.observe('allVisibleItemsHaveHeight', allVisibleItemsHaveHeight => {
        if (allVisibleItemsHaveHeight) {
          this.fire('initializedVisibleItems')
        }
      })

      let observedOnce = false

      this.observe('distanceFromBottom', (distanceFromBottom) => {
        if (!observedOnce) {
          observedOnce = true // TODO: the first time is always 0... need better way to handle this
          return
        }
        if (distanceFromBottom >= 0 &&
            distanceFromBottom <= DISTANCE_FROM_BOTTOM_TO_FIRE) {
          this.fireScrollToBottom()
        }
      })
    },
    data: () => ({
      component: null
    }),
    store: () => virtualListStore,
    components: {
      VirtualListLazyItem,
      VirtualListFooter
    },
    computed: {
      distanceFromBottom: ($scrollHeight, $scrollTop, $offsetHeight) => {
        return $scrollHeight - $scrollTop - $offsetHeight
      },
      // TODO: bug in svelte store, shouldn't need to do this
      allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight
    }
  }
</script>