<template>
  <div class="tags-nav">
    <ul v-show="visible" :style="{left: contextMenuLeft + 'px', top: '10px','line-height': '24px'}" class="contextmenu">
      <li v-for="(item, key) of menuList" @click="handleTagsOption(key)" :key="key">{{ item }}</li>
    </ul>
    <div class="btn-con right-btn">
<!--      <Button type="text" @click="handlePrevious" :disabled="this.currentTagIndex < 0">-->
      <Button type="text" @click="handlePrevious" class="tag-button">
        <Icon :size="18" type="ios-arrow-back"/>
      </Button>
<!--      <Button type="text" @click="handleNext" :disabled="this.currentTagIndex >= this.list.length - 1">-->
      <Button type="text" @click="handleNext" class="tag-button">
        <Icon :size="18" type="ios-arrow-forward" />
      </Button>
    </div>
    <div class="home-class">
      <tag :style="{width:'60px', marginLeft:'10px'}"
           :color="isCurrentTag({name:vm.$config.homeName}) ? 'default' :$config.tagNavCurrentColor"
           @contextmenu.native.prevent
           @click.native="handleClick({name:vm.$config.homeName})">
        {{ vm.$t(vm.$config.homeName) }}
      </tag>
    </div>
    <div class="scroll-outer" ref="scrollOuter">
      <div ref="scrollBody" class="scroll-body" :style="{left: tagBodyLeft + 'px'}" @DOMMouseScroll="handlescroll"
           @mousewheel="handlescroll">
        <transition-group name="taglist-moving-animation" style="display: flex;align-items: end">
          <Tag
            v-for="(item, index) in list"
            ref="tagsPageOpened"
            :key="`tag-nav-${index}`"
            :name="item.name"
            :style="item.name === vm.$config.homeName?'width:70px':''"
            :data-route-item="item"
            @on-close="handleClose(item)"
            @click.native="handleClick(item)"
            :closable="item.name !== $config.homeName"
            :color="isCurrentTag(item) ? 'default' :$config.tagNavCurrentColor"
            @contextmenu.prevent.native="contextMenu(item, $event)"
          >{{ showTitleInside(item) }}
          </Tag>

        </transition-group>

      </div>
    </div>
  </div>
</template>

<script>
import {showTitle, routeEqual} from '@/libs/base/util'
import beforeClose from '@/router/before-close'

export default {
  name: 'TagsNav',
  props: {
    value: Object,
    list: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    const vm = window.vm
    return {
      vm: vm,
      currentTagIndex: null,
      tagBodyLeft: 0,
      rightOffset: 40,
      outerPadding: 4,
      contextMenuLeft: 0,
      contextMenuTop: 0,
      scrollX: 0,
      currentRightRouteObj: {}, //记录右键在哪个菜单上
      visible: false,
      menuList: {
        others: this.$t('closeOthers'),
        all: this.$t('closeAll'),
        left: this.$t('closeLeft'),
        right: this.$t('closeRight'),
      }
    }
  },
  computed: {
    currentRouteObj() {
      const {name, params, query} = this.value
      return {name, params, query}
    }
  },
  methods: {
    /**
     * @desc   : 控制滚动
     * @author : 周兴
     * @date   : 2022/4/3 14:42
     */
    handlescroll(e) {
      let direction = e.deltaY > 0 ? '0' : '1'
      //下面的实现的是内部元素横向滚动，前提设置好内部元素横向的滚动样式了
      // let offsetLeft = this.$refs['scrollBody'].offsetLeft;
      let tag
      if (direction === '0') {
        this.$refs['scrollOuter'].scrollLeft += 30
        tag = this.$refs.tagsPageOpened[this.list.length - 1]
      } else {
        this.$refs['scrollOuter'].scrollLeft -= 30
        tag = this.$refs.tagsPageOpened[0]
      }
      this.moveToView(tag.$el)
    },
    /**
     * @desc   : 跳转到上一个
     * @author : 周兴
     * @date   : 2022/5/23 9:20
     */
    handlePrevious() {
      // let tagIndex = this.list.findIndex(item => item.name === this.currentRouteObj.name);
      // this.currentTagIndex = tagIndex - 1;
      // //当前在首页上
      // this.$emit('previousTag', this.currentTagIndex, this.currentRouteObj)
      this.handlescroll({deltaY: 0});
    },
    /**
     * @desc   : 跳转到下一个
     * @author : 周兴
     * @date   : 2022/5/23 9:20
     */
    handleNext() {
      // console.log('rrrd',this.$refs['scrollOuter'].scrollLeft,this.$refs['scrollOuter'].offsetLeft,this.$refs['scrollBody'].scrollLeft,this.$refs['scrollBody'].offsetLeft)
      // let tagIndex = this.list.findIndex(item => item.name === this.currentRouteObj.name);
      // if (tagIndex < this.list.length - 1) {
      //   this.currentTagIndex = tagIndex + 1;
      //   //当前在首页上
      //   this.$emit('nextTag', this.currentTagIndex, this.currentRouteObj)
      // }
      this.handlescroll({deltaY: 1});
    },
    /**
     * @desc   : 控制滚动
     * @author : 周兴
     * @date   : 2022/4/3 14:42
     */
    handleScroll(offset) {
      this.visible = false;
      //根据offset去判断是往前还是往后，切换tag,大于0是向前
      setTimeout(() => {
        if (offset > 0) {
          this.handlePrevious();
        } else {
          this.handleNext();
        }
      }, 200)
    },
    /**
     * @desc   : 点击右键面板的项
     * @author : 周兴
     * @date   : 2022/4/3 13:55
     */
    handleTagsOption(type) {
      if (type.includes('all')) {
        // 关闭所有，除了home 有提示信息的页面不关
        let res = this.list.filter(item => item.name === this.$config.homeName || item.meta.closeQuestion)
        this.$emit('on-close', res, 'all')
      } else if (type.includes('others')) {
        // 关闭除当前页和home页的其他页
        let res = this.list.filter(item => routeEqual(this.currentRightRouteObj, item) || item.name === this.$config.homeName ||item.meta.closeQuestion)
        this.$emit('on-close', res, 'others', this.currentRightRouteObj)
        setTimeout(() => {
          this.getTagElementByRoute(this.currentRightRouteObj)
        }, 100)
      } else if (type.includes('left')) {
        // 关闭左侧页除home页的其他页
        let flag = false;
        let list = []
        let res = []
        // 关闭左侧除当前页和home页的其他页
        this.list.forEach(item => {
          //首页需要放进去
          if (item.name === this.$config.homeName || item.meta.closeQuestion) {
            list.push(item.name);
            res.push(item);
          }
          //判断是否是当前页
          if (routeEqual(this.currentRightRouteObj, item)) {
            flag = true;
          }
          //从当前页进行记录
          if (flag) {
            list.push(item.name);
            res.push(item);
          }
        })
        this.$emit('on-close', res, 'left', this.currentRightRouteObj)
        setTimeout(() => {
          this.getTagElementByList(list)
        }, 100)
      } else if (type.includes('right')) {
        // 关闭右侧页除home页的其他页
        let flag = true;
        let list = []
        let res = []
        // 关闭左侧除当前页和home页的其他页
        this.list.forEach(item => {
          //从当前页进行记录
          if (flag || item.meta.closeQuestion) {
            list.push(item.name);
            res.push(item);
          }
          //判断是否是当前页
          if (routeEqual(this.currentRightRouteObj, item)) {
            flag = false;
          }
        })
        // console.log('right',list)
        this.$emit('on-close', res, 'right', this.currentRightRouteObj)
        setTimeout(() => {
          this.getTagElementByList(list)
        }, 100)
      }
    },
    /**
     * @desc   : 关闭页面
     * @author : 周兴
     * @date   : 2022/4/3 13:58
     */
    handleClose(current) {
      if (current.meta && current.meta.beforeCloseName && current.meta.beforeCloseName in beforeClose) {
        new Promise(beforeClose[current.meta.beforeCloseName]).then(close => {
          if (close) {
            this.close(current)
          }
        })
      } else {
        this.close(current)
      }
    },
    /**
     * @desc   : 关闭当前窗体
     * @author : 周兴
     * @date   : 2022/5/19 17:45
     */
    close(route) {
      let res = this.list.filter(item => !routeEqual(route, item))
      this.$emit('on-close', res, undefined, route)
    },
    /**
     * @desc   : Tag点击事件
     * @author : 周兴
     * @date   : 2022/5/19 19:57
     */
    handleClick(item) {
      this.$emit('input', item);
      this.$el.click();
      setTimeout(() => {
        //获取当前tag
        this.currentTagIndex = this.list.findIndex(item => item.name === this.currentRouteObj.name);
      }, 200)
    },
    /**
     * @desc   : 获取标题
     * @author : 周兴
     * @date   : 2022/5/17 21:48
     */
    showTitleInside(item) {

      let title = showTitle(item, this)
      // console.log('tilt',title,item)
      // if(item.meta && item.meta.hideInMenu){
      //   title = vm.$t(item.name);
      // }
      return title;
    },
    /**
     * @desc   : 判断是否是当前标签
     * @author : 周兴
     * @date   : 2022/5/17 21:49
     */
    isCurrentTag(item) {
      return routeEqual(this.currentRouteObj, item)
    },
    /**
     * @desc   : 滚动tag时，计算横向位置
     * @author : 周兴
     * @date   : 2023/2/17 10:03
     */
    moveToView(tag) {
      const outerWidth = this.$refs.scrollOuter.offsetWidth
      const bodyWidth = this.$refs.scrollBody.offsetWidth

      if (tag.offsetLeft === 0) {
        this.tagBodyLeft = 0
      } else if (bodyWidth < outerWidth) {
        this.tagBodyLeft = 0
      } else if (tag.offsetLeft < -this.tagBodyLeft) {
        // 标签在可视区域左侧
        this.tagBodyLeft = -tag.offsetLeft + this.outerPadding
      } else if (tag.offsetLeft > -this.tagBodyLeft && tag.offsetLeft + tag.offsetWidth < -this.tagBodyLeft + outerWidth) {
        // 标签在可视区域
        this.tagBodyLeft = Math.min(0, outerWidth - tag.offsetWidth - tag.offsetLeft - this.outerPadding)
      } else {
        // 标签在可视区域右侧
        this.tagBodyLeft = -(tag.offsetLeft - (outerWidth - this.outerPadding - tag.offsetWidth))
      }
      if (!this.tagBodyLeft) {
        this.tagBodyLeft = 0;
      }
    },
    /**
     * @desc   : 关闭左侧和关闭右侧使用
     * @author : 周兴
     * @date   : 2022/4/2 20:35
     */
    getTagElementByList(routeList) {
      this.$nextTick(() => {
        this.refsTag = this.$refs.tagsPageOpened
        if (this.refsTag) {
          this.refsTag.forEach((item, index) => {
            let routeItem = item.$attrs['data-route-item']
            if (routeList.indexOf(routeItem) >= 0) {
              let tag = this.refsTag[index].$el
              this.moveToView(tag)
            }
          })
        }
      })
    },
    /**
     * @desc   : 获取所要展示的页面
     * @author : 周兴
     * @date   : 2022/4/2 20:35
     */
    getTagElementByRoute(route) {
      this.$nextTick(() => {
        this.refsTag = this.$refs.tagsPageOpened
        if (this.refsTag) {
          this.refsTag.forEach((item, index) => {
            if (routeEqual(route, item.$attrs['data-route-item'])) {
              let tag = this.refsTag[index].$el
              this.moveToView(tag)
            }
          })
        }
      })
    },
    /**
     * @desc   : 打开右键菜单
     * @author : 周兴
     * @date   : 2022/4/3 13:45
     */
    contextMenu(item, e) {
      //首页不出现右键菜单
      if (item.name === this.$config.homeName) {
        return
      }
      // 记录在哪个菜单上打开的右键面板
      this.currentRightRouteObj = item;
      this.visible = true
      const offsetLeft = this.$el.getBoundingClientRect().left
      this.contextMenuLeft = e.clientX - offsetLeft + 10
      this.contextMenuTop = e.clientY - 64
    },
    closeMenu() {
      this.visible = false
    }
  },
  watch: {
    '$route'(to) {
      this.getTagElementByRoute(to)
    },
    visible(value) {
      if (value) {
        document.body.addEventListener('click', this.closeMenu)
      } else {
        document.body.removeEventListener('click', this.closeMenu)
      }
    },
    list(n, o) {
      //如果tag增加，那么右键弹出需要隐藏
      this.visible = false;
    }
  },
  mounted() {
    setTimeout(() => {
      this.getTagElementByRoute(this.$route)
    }, 200)
    //获取当前tag
    this.currentTagIndex = this.list.findIndex(item => item.name === this.currentRouteObj.name);
  }
}
</script>

<style lang="less">
@import './tags-nav.less';

</style>
