<:Window bind:online />
<div class="timeline" role="feed" aria-label="{{label}}" >
  <VirtualList component="{{StatusListItem}}"
               items="{{keyedStatuses}}"
               on:scrollToBottom="onScrollToBottom()" />
</div>
<style>
  .timeline {
    min-height: 50vh;
  }
</style>
<script>
  import { store } from '../_utils/store'
  import { getTimeline } from '../_utils/mastodon/timelines'
  import StatusListItem from './StatusListItem.html'
  import VirtualList from './VirtualList.html'
  import { splice, push } from 'svelte-extras'
  import {
    insertStatuses as insertStatusesIntoDatabase,
    getTimeline as getTimelineFromDatabase
  } from '../_utils/database/statuses'
  import { mergeStatuses } from '../_utils/statuses'
  import { mark, stop } from '../_utils/marks'
  import { timelines } from '../_static/timelines'

  const FETCH_LIMIT = 20

  export default {
    async oncreate() {
      let instanceName = this.store.get('currentInstance')
      let instanceData = this.store.get('currentInstanceData')
      let online = this.get('online')
      let statuses = online ?
        await getTimeline(instanceName, instanceData.access_token, this.get('timeline'), null, FETCH_LIMIT) :
        await getTimelineFromDatabase(instanceName, this.get('timeline'), null, FETCH_LIMIT)
      if (online) {
        insertStatusesIntoDatabase(instanceName, this.get('timeline'), statuses)
      }
      this.addStatuses(statuses)
      this.set({initialized: true})
    },
    data: () => ({
      StatusListItem: StatusListItem,
      statuses: [],
      runningUpdate: false,
      initialized: false
    }),
    computed: {
      keyedStatuses: (statuses) => statuses.map(status => ({
        props: status,
        key: status.id
      })),
      lastStatusId: (statuses) => statuses.length && statuses[statuses.length - 1].id,
      label: (timeline, $currentInstance) => `${timelines[timeline].label} timeline for ${$currentInstance}`
    },
    store: () => store,
    components: {
      VirtualList
    },
    methods: {
      splice: splice,
      push: push,
      async onScrollToBottom() {
        if (!this.get('initialized')) {
          return
        }
        if (this.get('runningUpdate')) {
          return
        }
        mark('onScrollToBottom')
        this.set({ runningUpdate: true })
        let lastStatusId = this.get('lastStatusId')
        let instanceName = this.store.get('currentInstance')
        let instanceData = this.store.get('currentInstanceData')
        let online = this.get('online')
        let newStatuses = online ?
          await getTimeline(instanceName, instanceData.access_token, this.get('timeline'), lastStatusId, FETCH_LIMIT) :
          await getTimelineFromDatabase(instanceName, this.get('timeline'), lastStatusId, FETCH_LIMIT)
        if (online) {
          insertStatusesIntoDatabase(instanceName, this.get('timeline'), newStatuses)
        }
        let statuses = this.get('statuses')
        if (statuses) {
          this.addStatuses(newStatuses)
        }
        this.set({ runningUpdate: false })
        stop('onScrollToBottom')
      },
      addStatuses(newStatuses) {
        if (process.env.NODE_ENV !== 'production') {
          console.log('addStatuses()')
        }
        let statuses = this.get('statuses')
        if (!statuses) {
          return
        }
        let merged = mergeStatuses(statuses, newStatuses)
        this.set({ statuses: merged })
      }
    }
  }
</script>