<template>
  <div class="l-main-tags">
    <!-- 标签页 -->
    <div class="l-main-tags__container">
      <scroll-pane ref="scrollPane" class="l-main-tags__list">
        <router-link
          v-for="tag in visitedViews"
          ref="tag"
          :class="isActive(tag) ? 'active' : ''"
          :to="{
            path: tag.path,
            query: tag.query,
            fullPath: tag.fullPath
          }"
          :key="tag.path"
          tag="span"
          class="l-main-tags__item"
          @click.middle.native="closeSelectedTag(tag)"
          @contextmenu.prevent.native="openMenu(tag, $event)"
        >
          <span class="l-main-tags__name" :title="generateTitle(tag.title)">{{ generateTitle(tag.title) }}</span>
          <span class="el-icon-close" v-if="tag.title !== '我的主页'" @click.prevent.stop="closeSelectedTag(tag)" />
        </router-link>
      </scroll-pane>
      <div class="l-main-tags__btn" v-show="showTagsList">
        <!-- 悬浮提示 -->
        <el-popover placement="top-start" popper-class="l-main-tags__popover" trigger="hover">
          <div class="l-dropdown-tags" :style="dropdownStyleHeight">
            <el-scrollbar wrap-class="l-dropdown-tags__wrapper">
              <div class="l-main-tags__inner">
                <router-link
                  v-for="tag in visitedViews"
                  :class="isActive(tag) ? 'active' : ''"
                  :to="{
                    path: tag.path,
                    query: tag.query,
                    fullPath: tag.fullPath
                  }"
                  :key="tag.path"
                  tag="span"
                  class="l-main-tags__item l-dropdown-tags__item"
                  @click.middle.native="closeSelectedTag(tag)"
                >
                  <span class="l-main-tags__name">{{ generateTitle(tag.title) }}</span>
                  <span class="el-icon-close" v-if="tag.title !== '我的主页'" @click.prevent.stop="closeSelectedTag(tag)" />
                </router-link>
              </div>
            </el-scrollbar>
          </div>
          <div class="l-main-tags__btn-inner" slot="reference">
            <i class="icon icon-bottom"></i>
            <span class="l-main-tags__btn-name">全部</span>
          </div>
        </el-popover>
      </div>
    </div>

    <!-- 右键操作区域 -->
    <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="l-main-tags__context">
      <li @click="refreshSelectedTag(selectedTag)">
        {{ $t('tagsView.refresh') }}
      </li>
      <li @click="closeSelectedTag(selectedTag)">
        {{ $t('tagsView.close') }}
      </li>
      <li @click="closeOthersTags">{{ $t('tagsView.closeOthers') }}</li>
      <li @click="closeAllTags">{{ $t('tagsView.closeAll') }}</li>
    </ul>
  </div>
</template>

<script>
import ScrollPane from '@/components/layout/scroll-pane';
import common from '@/common';
const { generateTitle } = common;

export default {
  components: { ScrollPane },
  data() {
    return {
      visible: false,
      top: 0,
      left: 0,
      selectedTag: {},
      showTagsList: false,
      dropdownListHeight: 100
    };
  },
  computed: {
    visitedViews() {
      return this.$store.state.tagsView.visitedViews;
    },
    dropdownStyleHeight() {
      return 'height: ' + this.dropdownListHeight + 'px;';
    }
  },
  watch: {
    $route() {
      this.addViewTags();
      this.moveToCurrentTag();
    },
    visible(value) {
      if (value) {
        document.body.addEventListener('click', this.closeMenu);
      } else {
        document.body.removeEventListener('click', this.closeMenu);
      }
    },
    /**
     * 检测标签页数目改变
     *
     */
    visitedViews() {
      this.iShowTagsBtn();
      this.dropdownTagsHeight();
    }
  },
  methods: {
    generateTitle, // generateTitle by vue-i18n
    isActive(route) {
      return route.path === this.$route.path;
    },
    addViewTags() {
      const { name } = this.$route;
      if (name) {
        this.$store.dispatch('addView', this.$route);
      }
      return false;
    },
    moveToCurrentTag() {
      const tags = this.$refs.tag;
      this.$nextTick(() => {
        for (const tag of tags) {
          if (tag.to.path === this.$route.path) {
            this.$refs.scrollPane.moveToTarget(tag);

            // when query is different then update
            if (tag.to.fullPath !== this.$route.fullPath) {
              this.$store.dispatch('updateVisitedView', this.$route);
            }

            break;
          }
        }
      });
    },
    refreshSelectedTag(view) {
      this.$store.dispatch('delCachedView', view).then(() => {
        const { fullPath } = view;
        this.$nextTick(() => {
          this.$router.replace({
            path: '/redirect' + fullPath
          });
        });
      });
    },
    closeSelectedTag(view) {
      this.$store.dispatch('delView', view).then(({ visitedViews }) => {
        if (this.isActive(view)) {
          const latestView = visitedViews.slice(-1)[0];
          if (latestView) {
            this.$router.push(latestView);
          } else {
            this.$router.push('/');
          }
        }
      });
    },
    closeOthersTags() {
      this.$router.push(this.selectedTag);
      this.$store.dispatch('delOthersViews', this.selectedTag).then(() => {
        this.moveToCurrentTag();
      });
    },
    closeAllTags() {
      this.$store.dispatch('delAllViews');
      this.$router.push('/');
    },
    openMenu(tag, e) {
      const menuMinWidth = 105;
      const offsetLeft = this.$el.getBoundingClientRect().left; // container margin left
      const offsetWidth = this.$el.offsetWidth; // container width
      const maxLeft = offsetWidth - menuMinWidth; // left boundary
      const left = e.clientX - offsetLeft + 16; // 16: margin right

      if (left > maxLeft) {
        this.left = maxLeft;
      } else {
        this.left = left;
      }
      this.top = e.clientY - 32;

      this.visible = true;
      this.selectedTag = tag;
    },
    closeMenu() {
      this.visible = false;
    },
    /**
     * 检测是否显示 Tags 全部按钮
     *
     */
    iShowTagsBtn() {
      this.$nextTick(() => {
        // 容器的宽度
        const offsetWidth = this.$el.offsetWidth;
        // 标签列表
        const tagsArray = this.$refs.tag; // tags list
        // 预留的空间位置
        const leaveSpace = 160;
        // 计算标签列表所占的宽度
        let tagsWrapperWidth = 0;

        // 检测标签列是否存在
        if (tagsArray) {
          // 计算列表宽度总和
          tagsArray.forEach((item) => {
            tagsWrapperWidth += item.$el.offsetWidth;
          });
        }

        // 测试
        // console.log(tagsArray, tagsWrapperWidth, offsetWidth, tagsWrapperWidth + leaveSpace > offsetWidth);

        // 更改显示值
        this.showTagsList = tagsWrapperWidth + leaveSpace > offsetWidth;
      });
    },
    /**
     * 计算下拉框的高度值
     */
    dropdownTagsHeight() {
      let _height = this.visitedViews.length * 36 + 10;
      let _windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

      // 自动计算高度值
      this.dropdownListHeight = _windowHeight - 180 < _height ? _windowHeight - 180 : _height;
    }
  },
  mounted() {
    // 添加标签页
    this.addViewTags();

    // 窗口 resize 监听事件
    window.addEventListener('resize', this.iShowTagsBtn);
    window.addEventListener('resize', this.dropdownTagsHeight);
  },
  beforeDestroy() {
    // 移除窗口监听事件
    window.removeEventListener('resize', this.iShowTagsBtn);
    window.removeEventListener('resize', this.dropdownTagsHeight);
  }
};
</script>
