<template>
  <div id="tabs-bar-container" class="tabs-bar-container">
    <el-tabs
      v-model="tabActive"
      type="card"
      class="tabs-content"
      @tab-click="handleTabClick"
      @tab-remove="handleTabRemove"
    >
      <el-tab-pane
        v-for="item in visitedRoutes"
        :key="item.path"
        :label="item.meta.title"
        :name="item.path"
        :closable="!isAffix(item)"
      ></el-tab-pane>
    </el-tabs>

    <el-dropdown @command="handleCommand">
      <span style="cursor: pointer">
        更多操作
        <i class="el-icon-arrow-down el-icon--right"></i>
      </span>
      <el-dropdown-menu slot="dropdown" class="tabs-more">
        <el-dropdown-item command="closeOtherstabs">
          <vab-icon :icon="['fas', 'times-circle']" />
          关闭其他
        </el-dropdown-item>
        <el-dropdown-item command="closeLefttabs">
          <vab-icon :icon="['fas', 'arrow-alt-circle-left']"></vab-icon>
          关闭左侧
        </el-dropdown-item>
        <el-dropdown-item command="closeRighttabs">
          <vab-icon :icon="['fas', 'arrow-alt-circle-right']"></vab-icon>
          关闭右侧
        </el-dropdown-item>
        <el-dropdown-item command="closeAlltabs">
          <vab-icon :icon="['fas', 'ban']"></vab-icon>
          关闭全部
        </el-dropdown-item>
      </el-dropdown-menu>
    </el-dropdown>
  </div>
</template>

<script>
  import path from 'path'
  import { mapGetters } from 'vuex'

  export default {
    name: 'VabTabsBar',
    data() {
      return {
        affixtabs: [],
        tabActive: '',
      }
    },

    computed: {
      ...mapGetters({
        visitedRoutes: 'tabsBar/visitedRoutes',
        routes: 'routes/routes',
      }),
    },
    watch: {
      $route: {
        handler(route) {
          this.inittabs()
          this.addtabs()
          let tabActive = ''
          this.visitedRoutes.forEach((item, index) => {
            if (item.path === this.$route.path) {
              tabActive = item.path
            }
          })
          this.tabActive = tabActive
        },
        immediate: true,
      },
    },
    mounted() {
      //console.log(this.visitedRoutes);
    },
    methods: {
      async handleTabRemove(tabActive) {
        let view
        this.visitedRoutes.forEach((item, index) => {
          if (tabActive == item.path) {
            view = item
          }
        })
        const { visitedRoutes } = await this.$store.dispatch(
          'tabsBar/delRoute',
          view
        )
        if (this.isActive(view)) {
          this.toLastTag(visitedRoutes, view)
        }
      },
      handleTabClick(tab) {
        const route = this.visitedRoutes.filter((item, index) => {
          if (tab.index == index) return item
        })[0]
        if (this.$route.path !== route.path) {
          this.$router.push({
            path: route.path,
            query: route.query,
            fullPath: route.fullPath,
          })
        } else {
          return false
        }
      },
      isActive(route) {
        return route.path === this.$route.path
      },
      isAffix(tag) {
        return tag.meta && tag.meta.affix
      },
      filterAffixtabs(routes, basePath = '/') {
        let tabs = []
        routes.forEach((route) => {
          if (route.meta && route.meta.affix) {
            const tagPath = path.resolve(basePath, route.path)
            tabs.push({
              fullPath: tagPath,
              path: tagPath,
              name: route.name,
              meta: { ...route.meta },
            })
          }
          if (route.children) {
            const temptabs = this.filterAffixtabs(route.children, route.path)
            if (temptabs.length >= 1) {
              tabs = [...tabs, ...temptabs]
            }
          }
        })
        return tabs
      },
      inittabs() {
        const affixtabs = (this.affixtabs = this.filterAffixtabs(this.routes))
        for (const tag of affixtabs) {
          if (tag.name) {
            this.$store.dispatch('tabsBar/addVisitedRoute', tag)
          }
        }
      },
      addtabs() {
        const { name } = this.$route
        if (name) {
          this.$store.dispatch('tabsBar/addVisitedRoute', this.$route)
        }
        return false
      },
      handleCommand(command) {
        switch (command) {
          case 'refreshRoute':
            this.refreshRoute()
            break
          case 'closeOtherstabs':
            this.closeOtherstabs()
            break
          case 'closeLefttabs':
            this.closeLefttabs()
            break
          case 'closeRighttabs':
            this.closeRighttabs()
            break
          case 'closeAlltabs':
            this.closeAlltabs()
            break
        }
      },
      async refreshRoute() {
        this.$baseEventBus.$emit('reloadrouter-view')
      },
      async closeSelectedTag(view) {
        const { visitedRoutes } = await this.$store.dispatch(
          'tabsBar/delRoute',
          view
        )
        if (this.isActive(view)) {
          this.toLastTag(visitedRoutes, view)
        }
      },
      async closeOtherstabs() {
        const view = await this.toThisTag()
        await this.$store.dispatch('tabsBar/delOthersRoutes', view)
      },
      async closeLefttabs() {
        const view = await this.toThisTag()
        await this.$store.dispatch('tabsBar/delLeftRoutes', view)
      },
      async closeRighttabs() {
        const view = await this.toThisTag()
        await this.$store.dispatch('tabsBar/delRightRoutes', view)
      },
      async closeAlltabs() {
        const view = await this.toThisTag()
        const { visitedRoutes } = await this.$store.dispatch(
          'tabsBar/delAllRoutes'
        )
        if (this.affixtabs.some((tag) => tag.path === view.path)) {
          return
        }
        this.toLastTag(visitedRoutes, view)
      },
      toLastTag(visitedRoutes, view) {
        const latestView = visitedRoutes.slice(-1)[0]
        if (latestView) {
          this.$router.push(latestView)
        } else {
          this.$router.push('/')
        }
      },
      async toThisTag() {
        const view = this.visitedRoutes.filter((item, index) => {
          if (item.path === this.$route.fullPath) {
            return item
          }
        })[0]
        if (this.$route.path !== view.path) this.$router.push(view)
        return view
      },
    },
  }
</script>

<style lang="scss" scoped>
  .tabs-bar-container {
    position: relative;
    box-sizing: border-box;
    display: flex;
    align-content: center;
    align-items: center;
    justify-content: space-between;
    height: $base-tabs-bar-height;
    padding-right: $base-padding;
    padding-left: $base-padding;
    user-select: none;
    background: $base-color-white;
    border-top: 1px solid #f6f6f6;

    ::v-deep {
      .fold-unfold {
        margin-right: $base-padding;
      }
    }

    .tabs-content {
      width: calc(100% - 90px);
      height: $base-tag-item-height;

      ::v-deep {
        .el-tabs__nav-next,
        .el-tabs__nav-prev {
          height: $base-tag-item-height;
          line-height: $base-tag-item-height;
        }

        .el-tabs__header {
          border-bottom: 0;

          .el-tabs__nav {
            border: 0;
          }

          .el-tabs__item {
            box-sizing: border-box;
            height: $base-tag-item-height;
            margin-right: 5px;
            line-height: $base-tag-item-height;
            border: 1px solid $base-border-color;
            border-radius: $base-border-radius;
            transition: padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) !important;

            &.is-active {
              border: 1px solid $base-color-blue;
            }
          }
        }
      }
    }

    .more {
      display: flex;
      align-content: center;
      align-items: center;
      cursor: pointer;
    }
  }
</style>