<template>
  <n-layout class="n-slide-navs">
    <n-content class="n-slide-navs-scroll" @scroll.native="onScroll">
      <slot></slot>
    </n-content>
    <template #footer>
      <n-slide-navigation-small v-if="isSmall" :data-list="blocks" :active="nValue" @click="scrollIndex"></n-slide-navigation-small>
      <div v-else class="n-slide-navs-large">
        <n-slide-navigation has-line has-text :data-list="blocks" :active="nValue" :hover.sync="hover" @click="scrollIndex"></n-slide-navigation>
      </div>
    </template>
  </n-layout>
</template>

<script>
import NLayout from '@uif/next/lib/components/layout'
import NContent from '@uif/next/lib/components/content'
import NSlideNavigation from './slide-navigation'
import NSlideNavigationSmall from './slide-navigation-small'
import {findChildComponents, scrollIntoView, scrollAfter, debounce, prop} from '@uif/next/lib/utils/tools'

export default {
  name: 'n-slide-navs',
  components: {
    NLayout,
    NContent,
    NSlideNavigation,
    NSlideNavigationSmall
  },
  props: {
    // 当前位置
    value: prop.number(),
    // 是否使用紧凑模式
    isSmall: prop.boolean()
  },
  data () {
    return {
      nValue: this.value,
      blocks: [],
      hover: -1,
      // 是否用户触发滚动
      isUserScroll: true
    }
  },
  watch: {
    value (value) {
      if (this.nValue !== value) {
        this.scrollIndex(value)
      }
    },
    nValue (nValue) {
      if (this.value !== nValue) {
        this.$emit('input', nValue)
        this.$emit('update:value', nValue)
      }
    }
  },
  mounted () {
    this.findBlocks()
    if (this.nValue !== 0) {
      this.scrollIndex(this.nValue)
    }
  },
  methods: {
    findBlocks (content) {
      this.blocks = findChildComponents(content || this, 'n-slide-block')
        .map(ref => ({title: ref.title, getRef: () => ref}))
    },
    // 滚动到index
    scrollIndex (index) {
      const block = this.blocks[index]
      if (block && this.nValue !== index) {
        this.isUserScroll = false
        this.setIndex(index)
        const el = block.getRef().$el
        return scrollAfter(el, 'top', () => scrollIntoView(el)).then(() => {
          this.isUserScroll = true
        })
      }
    },
    // 全部设置显示模式
    setAllValue (value) {
      this.blocks.forEach(block => block.getRef().setValue(value))
    },
    // 全部取消等待模式
    setAllLoaded () {
      this.blocks.forEach(block => block.getRef().setLoaded())
    },
    // 滚动时自动获取
    onScroll: debounce(function (event) {
      if (this.isUserScroll) {
        const offset = event.target.scrollTop + 36
        const index = this.blocks.findIndex(block => block.getRef().$el.offsetTop > offset) - 1
        this.setIndex(index >= 0 ? index : this.nValue)
      }
    }, 100),
    setIndex (index) {
      if (this.nValue !== index) {
        this.nValue = index
        this.$emit('u-update', index)
      }
    }
  }
}
</script>
