<template>
  <component :is="element" ref="content" @click="trackClick(item, index)">
    <slot v-if="intersected" />
    <slot v-else name="loading" />
  </component>
</template>

<script>
import { Hits } from '@mezereon/ui-components-vue'
import { mapState } from 'vuex'

export default {
  mixins: [Hits],
  name: 'MzLazyItem',
  props: {
    element: {
      type: String,
      default: 'div'
    },
    item: {
      type: Object,
      required: true
    },
    index: {
      type: Number,
      required: false
    }
  },
  data() {
    return {
      observer: null,
      intersected: false
    }
  },
  methods: {
    updateHtml(html) {
      this.$refs.content.innerHTML = html
      this.$el.classList.add('mz-lazy-item--loaded')
    },
    resetObserver() {
      let p = this.pagination
      if (
        this.intersected &&
        p.current_page > 1 &&
        (p.pagingType === 'more' || p.pagingType == 'infinite')
      ) {
        return
      }
      if (this.intersected) {
        this.intersected = false
        this.observer.observe(this.$el)
        this.$el.classList.remove('mz-lazy-item--loaded')
      }
    }
  },
  computed: {
    ...mapState('search', ['pagination'])
  },
  watch: {
    intersected(val, old) {
      if (val && this.$bus) {
        this.$bus.emit('lazy-load-item', this.$el, this.item, this.updateHtml)
      }
    }
  },
  mounted() {
    this.$bus.on('lazy-load-reset', this.resetObserver)
    this.observer = new IntersectionObserver((entries) => {
      const element = entries[0]
      if (element.isIntersecting) {
        this.intersected = true
        this.observer.disconnect()
      }
    })
    this.observer.observe(this.$el)
  },
  destroyed() {
    this.observer.disconnect()
  }
}
</script>
