<template>
  <div class="multi-tab">
    <div class="multi-tab-wrapper">
      <el-tabs
        v-model="activeKey"
        @edit="onEdit"
        type="card"
        style="background: #fff;margin: 0;padding-left: 16px;padding-top: 1px">
        <el-tab-pane
          v-for="(page, index) in pages"
          :key="page.fullPath"
          :name="page.path"
          :closable="pages.length > 1"
          stretch>
          <template slot="label">
            <el-popover
              popper-class="multi-tab-popper"
              :ref="'myPopover' + index"
              :visible-arrow="false"
              placement="bottom-start"
              width="80px"
              trigger="manual">
              <div class="popper-option" @click="handleClose('closeThat', page.fullPath)">
                <el-link :underline="false">关闭当前标签</el-link>
              </div>
              <div class="popper-option" @click="handleClose('closeRight', page.fullPath)">
                <el-link :underline="false">关闭右侧</el-link>
              </div>
              <div class="popper-option" @click="handleClose('closeLeft', page.fullPath)">
                <el-link :underline="false">关闭左侧</el-link>
              </div>
              <div class="popper-option" @click="handleClose('closeAll', page.fullPath)">
                <el-link :underline="false">关闭全部</el-link>
              </div>
              <span slot="reference" @contextmenu.prevent="closeMenuClick(page, index)">{{ page.meta.title }}</span>
            </el-popover>
          </template>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>
<script>
import events from './events'

export default {
  name: 'MultiTab',
  data () {
    return {
      fullPathList: [],
      pages: [],
      activeKey: '',
      newTabIndex: 0,
      visible: false,
    }
  },
  created () {
    // bind event
    events.$on('open', val => {
      if (!val) {
        throw new Error(`multi-tab: open tab ${val} err`)
      }
      this.activeKey = val
    }).$on('close', val => {
      if (!val) {
        this.closeThat(this.activeKey)
        return
      }
      this.closeThat(val)
    }).$on('rename', ({ key, name }) => {
      console.log('rename', key, name)
      try {
        const item = this.pages.find(item => item.path === key)
        item.meta.customTitle = name
        this.$forceUpdate()
      } catch (e) {
      }
    })

    this.pages.push(this.$route)
    this.fullPathList.push(this.$route.fullPath)
    this.selectedLastPath()
  },
  mounted () {
    window.addEventListener('click', this.clickOther)
  },
  methods: {
    onEdit (targetKey, action) {
      console.log(targetKey, action)
      this[action](targetKey)
    },
    remove (targetKey) {
      this.pages = this.pages.filter(page => page.fullPath !== targetKey)
      this.fullPathList = this.fullPathList.filter(path => path !== targetKey)
      // 判断当前标签是否关闭，若关闭则跳转到最后一个还存在的标签页
      if (!this.fullPathList.includes(this.activeKey)) {
        this.selectedLastPath()
      }
    },
    selectedLastPath () {
      this.activeKey = this.fullPathList[this.fullPathList.length - 1]
    },

    // content icon
    closeThat (e) {
      // 判断是否为最后一个标签页，如果是最后一个，则无法被关闭
      if (this.fullPathList.length > 1) {
        this.remove(e)
      } else {
        this.$message.info('这是最后一个标签了, 无法被关闭')
      }
    },
    closeLeft (e) {
      const currentIndex = this.fullPathList.indexOf(e)
      if (currentIndex > 0) {
        this.fullPathList.forEach((item, index) => {
          if (index < currentIndex) {
            this.remove(item)
          }
        })
      } else {
        this.$message.info('左侧没有标签')
      }
    },
    closeRight (e) {
      const currentIndex = this.fullPathList.indexOf(e)
      if (currentIndex < (this.fullPathList.length - 1)) {
        this.fullPathList.forEach((item, index) => {
          if (index > currentIndex) {
            this.remove(item)
          }
        })
      } else {
        this.$message.info('右侧没有标签')
      }
    },
    closeAll (e) {
      const currentIndex = this.fullPathList.indexOf(e)
      this.fullPathList.forEach((item, index) => {
        if (index !== currentIndex) {
          this.remove(item)
        }
      })
    },
    closeMenuClick (page, index) {
      this.clickOther()
      this.$refs['myPopover' + index][0].doShow()
    },
    handleClose(key, page) {
      this[key](page)
      this.clickOther()
    },
    clickOther() {
      for (const key in this.$refs) {
        if (key.indexOf('myPopover') !== -1) {
          if (this.$refs[key] && this.$refs[key][0] != null && this.$refs[key][0].showPopper) {
            this.$refs[key][0].doClose()
          }
        }
      }
    },
  },
  watch: {
    $route: function (newVal) {
      this.activeKey = newVal.fullPath
      if (this.fullPathList.indexOf(newVal.fullPath) < 0) {
        this.fullPathList.push(newVal.fullPath)
        this.pages.push(newVal)
      }
    },
    activeKey: function (newPathKey) {
      this.$emit('onRouterChange', newPathKey)
      if (this.$route.fullPath !== newPathKey) {
        this.$router.push({ path: newPathKey })
      }
    }
  },
  beforeDestroy () {
    window.removeEventListener('click', this.clickOther)
  },
}
</script>

<style lang="less" scoped>
  .multi-tab {
    .multi-tab-wrapper {
      .el-tabs {
        padding-left: 8px !important;
        /deep/.el-tabs__header {
          margin: 0;
        }
      }
    }
  }
</style>
