<template>
  <div class="bx-tab">
    <div class="bx-tab-scroller">
      <div
        class="bx-tab-wrap"
        :class="isAdaptive && 'bx-tab-adaptive'"
        >
        <slot />
      </div>
      <div
        class="bx-tab-line"
        :style="style"
        />
    </div>
  </div>
</template>
<script>
import { create } from '../utils/index'

export default create({
  name: 'tab',
  props: {
    index: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      currentIndex: this.index,
      isAdaptive: false,
      itemWidth: 0,
      lineWidth: 0,
      style: {},
    }
  },
  watch: {
    index(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.currentIndex = this.index
        this.calculateLineStyle()
        this.$emit('change', this.index)
      }
    },
  },
  methods: {
    init() {
      if (this.currentIndex >= this.$children.length) {
        this.currentIndex = this.$children.length - 1
      }
      if (this.currentIndex < 0) {
        this.currentIndex = 0
      }
      // 如果宽度小于屏幕宽度，则自适应
      let totalWidth = 0
      this.$children.forEach(item => {
        totalWidth += item.$el.clientWidth
      })
      if (totalWidth < this.$el.clientWidth) {
        this.isAdaptive = true
      }
      // 动态为每个项设置index
      this.$children.forEach((item, index) => {
        /* eslint no-param-reassign: ["error", { "props": false }] */
        item.$data.index = index
      })
      // 线条宽度
      this.lineWidth = this.$el.childNodes[0].lastChild.clientWidth
      // 渲染结束后，再动态设置line的样式
      this.$nextTick(() => {
        this.calculateLineStyle()
      })
    },
    // 计算style
    calculateLineStyle() {
      // tab项宽度
      this.itemWidth = this.$children[this.currentIndex].$el.clientWidth
      let left =
        this.$children[this.currentIndex].$el.offsetLeft +
        (this.itemWidth - this.lineWidth) / 2
      left = this.toFixed(left, 1)
      this.style = {
        left: `${left}px`,
        transitionProperty: 'left',
      }
    },
    // 重写toFixed函数
    toFixed(value, decimal) {
      const times = 10 ** decimal
      let des = value * times + 0.5
      des = parseInt(des, 10) / times
      des = des.toFixed(decimal)
      return `${des}`
    },
    // tab项改变监听
    itemListener() {
      this.$on('change-item', index => {
        this.currentIndex = index
        this.calculateLineStyle()
        this.$emit('change', index)
      })
    },
    // resize监听
    resizeListener() {
      const self = this
      window.addEventListener(
        'resize',
        () => {
          self.calculateLineStyle()
        },
        false,
      )
    },
  },
  mounted() {
    this.init()
    this.itemListener()
    this.resizeListener()
  },
})
</script>
<style lang="postcss">
@import './index.css';
</style>
