<template>
  <div class="tags-header">
    <div class="tags-header__arrow left" @click="handleLeft" v-if="barWidth > boxWidth"
      ><i class="el-icon-arrow-left"
    /></div>
    <div class="tags-header__content" ref="content">
      <div class="scroll-bar" ref="bar">
        <li
          :class="{ active: index === activeIndex }"
          v-for="(item, index) in list"
          :key="index"
          @click="handleActive(index)"
        >
          <i class="refresh el-icon-refresh" @click.stop="handleRefresh(item)" />
          <span>{{ item.title }}</span>
          <i class="close el-icon-close" @click.stop="handleClose(index)" v-if="list.length > 1" />
        </li>
      </div>
    </div>
    <div class="tags-header__arrow right" @click="handleRight" v-if="barWidth > boxWidth"
      ><i class="el-icon-arrow-right"
    /></div>
  </div>
</template>
<script>
import { mapState } from 'vuex'
export default {
  componentName: 'TagsHeader',
  computed: {
    ...mapState({
      list: (state) => state.tagHeader.list,
      activeIndex: (state) => state.tagHeader.activeIndex
    })
  },
  watch: {
    list: {
      handler(value) {
        this.resetBarWidth()
      },
      deep: true
    },
    activeIndex(value) {
      this.$nextTick(() => {
        if (value < 0) {
          this.$store.dispatch('tagHeader/active', 0)
        } else {
          let page = this.list[value]
          this.$router.push(page.fullPath)
          this.resetLocation(value)
        }
      })
    }
  },
  data() {
    return {
      barWidth: 0,
      boxWidth: 0,
      loadEnd: false
    }
  },
  created() {
    this.updateRouter(this.$route)
    this.$router.beforeEach((to, from, next) => {
      this.updateRouter(to, from)
      next()
    })
  },
  mounted() {
    this.$nextTick(() => {
      this.boxWidth = this.$refs.content.offsetWidth
      this.barWidth = this.$refs.bar.offsetWidth
    })
  },
  methods: {
    /**
     * @description: 选择标签
     * @param {type}
     * @return:
     */
    handleActive(index) {
      this.$store.dispatch('tagHeader/active', index)
    },
    /**
     * @description: 关闭标签
     * @param {type}
     * @return:
     */
    handleClose(index) {
      this.$store.dispatch('tagHeader/close', index)
    },
    /**
     * @description: 选中横向定位
     * @param {type}
     * @return:
     */
    resetLocation(index) {
      this.$nextTick(() => {
        let liLeft = this.$refs.bar.querySelectorAll(`li`)[index].offsetLeft,
          liWidth = this.$refs.bar.querySelectorAll(`li`)[index].offsetWidth,
          barLeft = this.$refs.content.scrollLeft
        if (!(liLeft - 100 > barLeft && liLeft + liWidth < barLeft + this.boxWidth - 30)) {
          this.$refs.content.scrollLeft = liLeft - 100
        }
      })
    },
    /**
     * @description: 往左滚动
     * @param {type}
     * @return:
     */
    handleLeft() {
      let left = this.$refs.content.scrollLeft
      this.$refs.content.scrollLeft = Math.max(left - this.boxWidth, 0)
    },
    /**
     * @description: 往右滚动
     * @param {type}
     * @return:
     */
    handleRight() {
      let left = this.$refs.content.scrollLeft
      this.$refs.content.scrollLeft = Math.min(
        left + this.boxWidth,
        this.barWidth - this.boxWidth + 100
      )
    },
    /**
     * @description: 重置bar宽度
     * @param {type}
     * @return:
     */
    resetBarWidth() {
      this.$nextTick(() => {
        this.barWidth = this.$refs.bar.offsetWidth
      })
    },
    /**
     * @description: 刷新
     * @param {type}
     * @return:
     */
    handleRefresh(item) {
      this.$store.dispatch('tagHeader/closeCached', item.name).then(() => {
        this.$router.replace({
          path: `/redirect${item.fullPath}`
        })
      })
    },
    /**
     * @description: 更新路由
     * @param {type}
     * @return:
     */
    updateRouter(value) {
      if (value.name === 'refresh') return
      let findIndex = undefined,
        refreshItem = {}
      this.list.forEach((item, index) => {
        if (item.path === value.path) {
          if (item.fullPath !== value.fullPath) {
            item.fullPath = value.fullPath
            refreshItem = {
              ...value,
              index: index
            }
          }
          this.$store.dispatch('tagHeader/addCached', { name: value.name })
          findIndex = index
        }
      })
      if (refreshItem && refreshItem.name) {
        this.$store.dispatch('tagHeader/active', refreshItem.index)
        this.$store.dispatch('tagHeader/closeCached', refreshItem.name).then(() => {
          this.$nextTick(() => {
            this.$store.dispatch('tagHeader/addCached', {
              name: refreshItem.name
            })
          })
        })
      } else if (findIndex === undefined) {
        this.$store.dispatch('tagHeader/add', value)
      } else {
        this.$store.dispatch('tagHeader/active', findIndex)
      }
    }
  }
}
</script>
<style lang="less" scoped>
@import '~styles/var.less';
.tags-header {
  height: 40px;
  margin: 0 15px 15px;
  background: #fff;
  display: flex;
  border-bottom: 2px solid @color-primary;
  &__content {
    flex: 1;
    overflow: hidden;
    transition: 0.3s;
    position: relative;
    .scroll-bar {
      display: inline-block;
      white-space: nowrap;
      position: relative;
    }
  }
  li {
    display: inline-block;
    list-style-type: none;
    min-width: 120px;
    padding: 0 30px;
    line-height: 40px;
    font-size: 14px;
    position: relative;
    transition: 0.2s;
    border-right: 1px solid @border-color-base;
    .close,
    .refresh {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      font-size: 14px;
      transition: 0.2s;
      display: none;
    }
    .refresh {
      left: 8px;
    }
    .close {
      right: 8px;
    }
    &.active,
    &:hover {
      cursor: pointer;
      color: #fff;
      background: @color-primary;
      .close,
      .refresh {
        color: #fff;
        display: block;
      }
    }
  }
  &__arrow {
    width: 30px;
    flex: none;
    line-height: 40px;
    text-align: center;
    cursor: pointer;
    &:hover {
      color: #fff;
      background: @color-primary;
    }
    &.left {
      left: 0;
      border-right: 1px solid @border-color-base;
    }
    &.right {
      border-left: 1px solid @border-color-base;
      right: 0;
    }
  }
}
</style>
