<template>
  <div class="sv-index-list-wrapper">
    <ul class="sv-index-list hidden">
      <slot></slot>
    </ul>
    <div class="sv-index-mark" v-if="isScrolling">{{markText}}</div>
    <div class="sv-index-list" ref="indexListRef">
      <div class="sv-index-section" v-for="(value, key, $index) in indexListObject" ref="indexSectionRef" :class="{'active': $index === currentSectionIndex}">
        <sv-index-item is-divider>{{key}}</sv-index-item>
        <sv-index-item v-for="text in indexListObject[key]" :key="text">{{text}}</sv-index-item>
      </div>
    </div>
    <ul class="sv-index-handle" ref="indexHandleRef">
      <li class="sv-index-handle-letter" v-for="(value, key, $index) in indexListObject" :class="{'active': $index === currentHandleIndex}">{{key}}</li>
    </ul>
    <i class="sv-index-indicator" :class="{'active': isShowIndicator}" v-if="showIndicator">{{markText}}</i>
  </div>
</template>

<script type="text/ecmascript-6">
  import PinYin from './pinyin'
  export default {
    name: 'svIndexList',
    props: {
      showIndicator: {
        type: Boolean,
        default: false
      }

    },
    data () {
      return {
        indexListObject: {},
        currentSectionIndex: 0, // 当前激活的字母索引，即处于页面顶部的字母索引
        currentHandleIndex: 0, // 当前激活的手柄处的字母索引
        isScrolling: false,
        isShowIndicator: false
      }
    },
    computed: {
      markText () {
        return Object.keys(this.indexListObject)[this.currentHandleIndex]
      }
    },
    methods: {
      getIndexListObject () {
        let children = this.$children
        let texts = []
        if (children && children.length > 0) {
          children.forEach(child => {
            if (child.$slots.title && child.$slots.title.length > 0) {
              texts.push(child.$slots.title[0].text)
            } else if (child.$slots.default && child.$slots.default.length > 0) {
              texts.push(child.$slots.default[0].text)
            }
          })
        }

        let indexListObject = {}
        texts.forEach(text => {
          let firstLetter = PinYin.getFirstLetter(text, true)
          if (!indexListObject[firstLetter]) {
            indexListObject[firstLetter] = []
            indexListObject[firstLetter].push(text)
          } else {
            indexListObject[firstLetter].push(text)
          }
        })

        let letters = Object.keys(indexListObject).sort()
        let indexListObjectBySort = {}
        letters.forEach(letter => {
          indexListObjectBySort[letter] = indexListObject[letter].sort((val1, val2) => val1.localeCompare(val2, 'zh-Hans-CN', {sensitivity: 'accent'}))
        })
        return indexListObjectBySort
      },
      getPageScrollTop () {
        if (window.pageYOffset) {
          return window.pageYOffset
        } else if (document.documentElement && document.documentElement.scrollTop) {
          return document.documentElement.scrollTop
        } else if (document.body) {
          return document.body.scrollTop
        }
        return 0
      },
      handleIndexListScroll () {
        let scrollTop = 0
        let currentSectionIndex = 0
        window.addEventListener('scroll', event => {
          scrollTop = this.getPageScrollTop()
          this.$refs.indexSectionRef.forEach((section, index) => {
            if (scrollTop > section.offsetTop) {
              currentSectionIndex = index
            }
          })

          this.currentSectionIndex = this.currentHandleIndex = currentSectionIndex
          this.isScrolling = scrollTop > 0
        })
      },
      handleIndexHandleScroll () {
        this.$nextTick(() => { // 不加这句下面的offsetHeight将为0
          let clientY
          let indexHandleDistanceToTop = this.$refs.indexHandleRef.offsetTop - (this.$refs.indexHandleRef.offsetHeight / 2)
          let moveDistanceToTop
          let currentHandleIndex = 0
          let handleItemCount = this.$refs.indexHandleRef.childNodes.length

          this.$refs.indexHandleRef.addEventListener('touchstart', event => {
            event.stopPropagation()
            event.preventDefault()
            clientY = event.touches[0].clientY
            moveDistanceToTop = clientY - indexHandleDistanceToTop
            currentHandleIndex = Math.floor(moveDistanceToTop / (this.$refs.indexHandleRef.offsetHeight / handleItemCount))

            if (currentHandleIndex < 0) {
              currentHandleIndex = 0
            }
            if (currentHandleIndex > handleItemCount - 1) {
              currentHandleIndex = handleItemCount - 1
            }
            this.currentHandleIndex = currentHandleIndex

            this.slide(this.currentHandleIndex)
            this.isShowIndicator = true
          })
          this.$refs.indexHandleRef.addEventListener('touchmove', event => {
            event.stopPropagation()
            event.preventDefault()
            clientY = event.touches[0].clientY
            moveDistanceToTop = clientY - indexHandleDistanceToTop
            currentHandleIndex = Math.floor(moveDistanceToTop / (this.$refs.indexHandleRef.offsetHeight / handleItemCount))

            if (currentHandleIndex < 0) {
              currentHandleIndex = 0
            }
            if (currentHandleIndex > handleItemCount - 1) {
              currentHandleIndex = handleItemCount - 1
            }
            this.currentHandleIndex = currentHandleIndex

            this.slide(this.currentHandleIndex)
            this.isShowIndicator = true
          })
        })

        this.$refs.indexHandleRef.addEventListener('touchend', event => {
          this.isShowIndicator = false
        })
      },
      slide (index) {
        let currentSectionOffsetTop = this.$refs.indexSectionRef[index].offsetTop
        let documentHeight = this.$el.offsetHeight
        let clientHeight = document.documentElement.clientHeight
        if (documentHeight - currentSectionOffsetTop < clientHeight) {
          if (documentHeight - document.documentElement.scrollTop > clientHeight) {
            window.scrollTo(0, documentHeight - clientHeight) // 页面滚动到底部
          }
          return
        }
        window.scrollTo(0, currentSectionOffsetTop)
      }
    },
    mounted () {
      this.indexListObject = this.getIndexListObject()
      this.handleIndexListScroll()
      this.handleIndexHandleScroll()
    }
  }
</script>

<style lang="scss" rel="stylesheet/scss">
  @import "../../styles/base";
  ul, li{
    margin:0;
    padding:0;
    list-style: none;
  }
  .sv-index-list-wrapper{
    &::-webkit-scrollbar{
      display: none;
      width: 0;
    }
    .sv-index-mark{
      position: fixed;
      top:0;
      z-index: 2;
      width: 100%;
      padding-left: pxToRem(30);
      border-bottom: 1px solid #ccc;
      background: $color-light;
      color:$color-success;
      line-height: pxToRem(30);
    }
    .sv-index-list{
      &.hidden{
        display: none;
      }
      .sv-index-section{
        &.active{
        }
      }
    }
    .sv-index-handle{
      position: fixed;
      top:50%;
      right:pxToRem(10);
      transform: translateY(-50%);
      font-size: pxToRem(20);
      color:#333;
      .sv-index-handle-letter{
        display: flex;
        justify-content: center;
        align-items: center;
        padding: pxToRem(10 0);
        line-height: 1;
        &:not(:last-child){
        }
        &.active{
          width: pxToRem(30);
          height: pxToRem(30);
          border-radius: 50%;
          background:$color-success;
          color:$color-light;

        }
      }
    }
    .sv-index-indicator{
      position: fixed;
      top: 50%;
      left:50%;
      transform: translate(-50%, -50%);
      display: flex;
      justify-content: center;
      align-items: center;
      width: pxToRem(100);
      height: pxToRem(100);
      border-radius: pxToRem(20);
      background: rgba(0, 0, 0, .6);
      color:$color-light;
      font-size: pxToRem(40);
      font-style: normal;

      opacity: 0;
      transition: opacity .8s ease-out;
      &.active{
        opacity: 1;
        transition: opacity 0s;
      }
    }
  }
</style>
