<template>
  <div class="tags-view__container">
    <scroll-pane ref="scrollPaneRef" class="tags-view__wrapper" @scroll="handleScroll">
      <router-link v-for="tag in visitedViews" :key="tag.path" :data-path="tag.path"
        :class="isActive(tag) ? 'active' : ''" :to="{ path: tag.path }" class="tags-view__item"
        @click.middle="closeSelectedTag(tag)" @contextmenu.prevent="openMenu(tag, $event)">
        <div class="tags-view__content">
          {{ generateTitle(tag.meta.title) }}
          <span v-if="visitedViews.length > 1" class="icon-close" @click.prevent.stop="closeSelectedTag(tag)">
            <svg-icon icon-class="close" />
          </span>
        </div>
      </router-link>
    </scroll-pane>
    <ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="tags-view__menu">
      <!-- <li @click="refreshSelectedTag(selectedTag)">
        刷新
      </li> -->
      <li v-if="visitedViews.length > 1" @click="closeSelectedTag(selectedTag)">
        关闭
      </li>
      <li v-if="visitedViews.length > 1" @click="closeOtherTags">
        关闭其它
      </li>
      <li v-if="!isFirstView()" @click="closeLeftTags">
        关闭左侧
      </li>
      <li v-if="!isLastView()" @click="closeRightTags">
        关闭右侧
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts">
import {
  computed,
  getCurrentInstance,
  nextTick,
  ref,
  watch,
  onMounted,
  ComponentInternalInstance
} from 'vue';

import path from 'path-browserify';

import { useRoute, useRouter } from 'vue-router';

import ScrollPane from './ScrollPane.vue';
import SvgIcon from '@/components/SvgIcon/index.vue';
import { generateTitle } from '@/utils/i18n';
import useStore from '@/store';
import { TagView } from '@/store/modules/types';

const { tagsView, app } = useStore();

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const router = useRouter();
const route = useRoute();

const visitedViews = computed<any>(() => tagsView.visitedViews);

const routes = computed<any>(() => app.routes);

const affixTags = ref([]);
const visible = ref(false);
const selectedTag = ref({});
const scrollPaneRef = ref();
const left = ref(0);
const top = ref(0);

watch(
  route,
  () => {
    addTags();
    moveToCurrentTag();
  },
  {
    //初始化立即执行
    immediate: true
  }
);

watch(visible, value => {
  if (value) {
    document.body.addEventListener('click', closeMenu);
  } else {
    document.body.removeEventListener('click', closeMenu);
  }
});

function filterAffixTags(routes: any[], basePath = '/') {
  let tags: TagView[] = [];

  routes.forEach(route => {
    if (route.meta && route.meta.affix) {
      const tagPath = path.resolve(basePath, route.path);
      tags.push({
        fullPath: tagPath,
        path: tagPath,
        name: route.name,
        meta: { ...route.meta }
      });
    }

    if (route.children) {
      const childTags = filterAffixTags(route.children, route.path);
      if (childTags.length >= 1) {
        tags = tags.concat(childTags);
      }
    }
  });
  return tags;
}

function initTags() {
  const res = filterAffixTags(routes.value) as [];
  affixTags.value = res;
  for (const tag of res) {
    // Must have tag name
    if ((tag as TagView).name) {
      tagsView.addVisitedView(tag);
    }
  }
}

function addTags() {
  if (route.name) {
    tagsView.addView(route);
  }
}

function moveToCurrentTag() {
  nextTick(() => {
    for (const r of visitedViews.value) {
      if (r.path === route.path) {
        scrollPaneRef.value.moveToTarget(r);
        // when query is different then update
        if (r.fullPath !== route.fullPath) {
          tagsView.updateVisitedView(route);
        }
      }
    }
  });
}

function isActive(tag: TagView) {
  return tag.path === route.path;
}
function isFirstView() {
  try {
    return (
      (selectedTag.value as TagView).fullPath ===
      visitedViews.value[0].fullPath ||
      (selectedTag.value as TagView).fullPath === '/index'
    );
  } catch (err) {
    return false;
  }
}

function isLastView() {
  try {
    return (
      (selectedTag.value as TagView).fullPath ===
      visitedViews.value[visitedViews.value.length - 1].fullPath
    );
  } catch (err) {
    return false;
  }
}
function refreshSelectedTag(view: TagView) {
  tagsView.delCachedView(view);
  const { fullPath } = view;

  console.log('/vue-web' + fullPath, 'fullPath')
  nextTick(() => {
    router.push({ path: fullPath });
  });
}

function toLastView(visitedViews: TagView[], view?: any) {
  const latestView = visitedViews.slice(-1)[0];
  if (latestView && latestView.fullPath) {
    router.push(latestView.fullPath);
  }
}

function closeSelectedTag(view: TagView) {
  tagsView.delView(view).then((res: any) => {
    if (isActive(view)) {
      toLastView(res.visitedViews, view);
    }
  });
  //清除页面缓存
  tagsView.delCachedView(view)
}

function closeOtherTags() {
  // for (const r of visitedViews.value) {
  //   if (r.path === route.path) {
  //     selectedTag.value = r;
  //     break;
  //   }
  // }
  router.push(selectedTag.value);
  tagsView.delOtherViews(selectedTag.value).then(() => {
    moveToCurrentTag();
  });
}

function closeLeftTags() {
  tagsView.delLeftViews(selectedTag.value).then((res: any) => {
    if (
      !res.visitedViews.find((item: any) => item.fullPath === route.fullPath)
    ) {
      toLastView(res.visitedViews);
    }
  });
}
function closeRightTags() {
  tagsView.delRightViews(selectedTag.value).then((res: any) => {
    if (
      !res.visitedViews.find((item: any) => item.fullPath === route.fullPath)
    ) {
      toLastView(res.visitedViews);
    }
  });
}

function openMenu(tag: TagView, e: MouseEvent) {
  const menuMinWidth = 105;
  const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left
  const offsetWidth = proxy?.$el.offsetWidth; // container width
  const maxLeft = offsetWidth - menuMinWidth; // left boundary
  const l = e.clientX - offsetLeft + 15; // 15: margin right

  if (l > maxLeft) {
    left.value = maxLeft;
  } else {
    left.value = l;
  }

  top.value = e.clientY - 35;
  visible.value = true;
  selectedTag.value = tag;
}

function closeMenu() {
  visible.value = false;
}

function handleScroll() {
  closeMenu();
}

onMounted(() => {
  initTags();
});
</script>

<style lang="scss" scoped>
@import 'src/styles/variables.module';

.tags-view__container {
  height: 20px;
  width: 100%;
  background: #DAE6F4;
  box-shadow: inset 0 0 3px 0 rgba(0, 0, 0, 0.20);
  border-bottom: 1px solid $primaryColor;
  position: relative;

  .closeOther {
    position: absolute;
    cursor: pointer;
    right: 20px;
    top: 2px;
    font-size: 14px;
    color: $primaryColor;
    z-index: 1;
  }

  .tags-view__wrapper {
    .tags-view__item {
      display: inline-block;
      position: relative;
      cursor: pointer;
      height: 18px;
      line-height: 18px;
      background: transparent;
      color: #333333;
      padding: 0 9px;
      font-size: 12px;
      margin-top: 1px;
      border-top-right-radius: 4px;
      border-top-left-radius: 4px;

      //.tags-view__content{
      //  padding: 0 8px;
      //}
      &:first-of-type {
        margin-left: 15px;
      }

      &:last-of-type {
        margin-right: 15px;
      }

      &:hover {
        color: $primaryColor;
      }

      &.active {
        background-color: $primaryColor;
        color: #ffffff;
        border-color: $primaryColor;

        &:before {
          position: absolute;
          left: -5px;
          bottom: 0px;
          width: 5px;
          height: 5px;
          background-color: $primaryColor;
          content: "";
        }

        &:after {
          position: absolute;
          right: -5px;
          bottom: 0px;
          width: 5px;
          height: 5px;
          background-color: $primaryColor;
          content: "";
        }

        .tags-view__content {
          &:before {
            position: absolute;
            z-index: 2;
            left: -9px;
            bottom: 0px;
            width: 9px;
            height: 9px;
            background-color: #DAE6F4;
            content: "";
            border-radius: 100%;
          }

          &:after {
            position: absolute;
            z-index: 2;
            right: -9px;
            bottom: 0px;
            width: 9px;
            height: 9px;
            background-color: #DAE6F4;
            content: "";
            border-radius: 100%;
          }
        }
      }

      .icon-close {
        border-radius: 50%;
        text-align: center;

        &:hover {
          background-color: #ccc;
          color: #fff;
        }
      }
    }

    .tags-view__item.active {}
  }

  .tags-view__menu {
    margin: 0;
    background: #fff;
    z-index: 3000;
    position: absolute;
    list-style-type: none;
    padding: 5px 0;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 400;
    color: #333;
    box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);

    li {
      margin: 0;
      padding: 7px 16px;
      cursor: pointer;

      &:hover {
        background: #eee;
      }
    }
  }
}
</style>
