<template>
  <div class="tags-view" :class="{ 'dark-tags-view': settingStore.darkTheme }">
    <a-tabs
      v-model:activeKey="activeKey"
      hide-add
      type="editable-card"
      @change="goPage"
      @edit="onEdit"
      size="small"
      :tabBarGutter="6"
      :tabBarStyle="{
        margin: 0,
      }"
    >
      <a-tab-pane
        v-for="item in tabsList"
        :key="item.key"
        :tab="item.title"
        :closable="!item.meta?.affix"
      />
      <template #rightExtra>
        <div class="tabs-close">
          <a-dropdown placement="bottomLeft">
            <div class="tabs-close-btn">
              <DownOutlined />
            </div>
            <template #overlay>
              <a-menu>
                <a-menu-item @click="fullScreen">
                  <a-space>
                    <ExpandOutlined v-if="!getPageFullScreen" />
                    <CompressOutlined v-else />
                    <span>{{ getPageFullScreen ? '退出全屏' : '内容全屏' }}</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item @click="reloadPage">
                  <a-space>
                    <SyncOutlined />
                    <span>刷新当前</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item :disabled="currentRoute.meta?.affix" @click="closeCurrentTabItem">
                  <a-space>
                    <MinusOutlined />
                    <span>关闭当前</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item @click="closeOther">
                  <a-space>
                    <SwapOutlined />
                    <span>关闭其他</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item @click="closeLeft">
                  <a-space>
                    <DoubleLeftOutlined />
                    <span>关闭左侧</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item @click="closeRight">
                  <a-space>
                    <DoubleRightOutlined />
                    <span>关闭右侧</span>
                  </a-space>
                </a-menu-item>
                <a-menu-item @click="closeAll">
                  <a-space>
                    <CloseOutlined />
                    <span>关闭全部</span>
                  </a-space>
                </a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </div>
      </template>
    </a-tabs>
  </div>
</template>

<script lang="ts" setup>
  import { computed, ref, watch, inject } from 'vue';
  import { useRoute, useRouter } from 'vue-router';
  import { storage } from '@/utils/Storage';
  import { RouteItem } from '@/store/modules/tabsView';
  import { TABS_ROUTES,FIRST_ROUTE } from '@/store/mutation-types';
  import { useGo, useRedo } from '@/hooks/web/usePage';
  import { PageEnum } from '@/enums/pageEnum';
  import { useTabsViewStore } from '@/store/modules/tabsView';
  import {
    DownOutlined,
    SyncOutlined,
    CloseOutlined,
    MinusOutlined,
    SwapOutlined,
    DoubleLeftOutlined,
    DoubleRightOutlined,
    ExpandOutlined,
    CompressOutlined,
  } from '@ant-design/icons-vue';
  import { useProjectSettingStore } from '@/store/modules/projectSetting';
  import { useAsyncRouteStore } from '@/store/modules/asyncRoute';

  // 获取简易的路由对象
  const getSimpleRoute = (route): RouteItem => {
    const { fullPath, hash, meta, name, params, path, query } = route;
    return { fullPath, hash, meta, name, params, path, query };
  };

  const emit = defineEmits(['pageFullScreen']);

  const route = useRoute();
  const router = useRouter();
  const go = useGo();
  const currentTabRoute = ref(null);
  const refreshCurrent = ref(true);
  const currentRoute = ref(route);
  const activeKey = ref(route.name);
  const tabsViewStore = useTabsViewStore();
  const settingStore = useProjectSettingStore();
  const asyncRouteStore = useAsyncRouteStore();

  let routes: RouteItem[] = [];
  try {
    const routesStr = storage.get(TABS_ROUTES) as string | null | undefined;
    routes = routesStr ? JSON.parse(routesStr) : [getSimpleRoute(route)];
  } catch (e) {
    routes = [getSimpleRoute(route)];
  }
  // 初始化标签页
  tabsViewStore.initTabs(routes);

  const getPageFullScreen = inject('isPageFullScreen');

  //当前路由对象 或者 右键选择tab路由对象
  const getCurrentTabRoute = computed(() =>
    currentTabRoute.value ? currentTabRoute.value : route,
  );

  // 移除缓存组件名称
  const delKeepAliveCompName = () => {
    if (route.meta.keepAlive) {
      const name = router.currentRoute.value.matched.find((item) => item.name == route.name)
        ?.components?.default.name;
      if (name) {
        asyncRouteStore.keepAliveComponents = asyncRouteStore.keepAliveComponents.filter(
          (item) => item != name,
        );
      }
    }
  };

  // 标签页列表
  const tabsList: any = computed(() => {
    return tabsViewStore.tabsList.map((item) => {
      return {
        ...item,
        title: item.meta?.title,
        key: item.fullPath,
        closable: !item.meta?.affix,
      };
    });
  });

  const whiteList: string[] = [
    PageEnum.BASE_LOGIN_NAME,
    PageEnum.REDIRECT_NAME,
    PageEnum.ERROR_PAGE_NAME,
  ];

  watch(
    () => route.fullPath,
    (to) => {
      // 如果您用的路由模式是 hash 请去掉，|| route.hash 判断条件
      if (whiteList.includes(route.name as string) || route.hash || route.meta.tagView === false)
        return;
      activeKey.value = to;
      currentTabRoute.value = null;
      currentRoute.value = route;
      refreshCurrent.value = false;
      tabsViewStore.addTabs(getSimpleRoute(route));
    },
    { immediate: true },
  );

  //内容页全屏
  function fullScreen() {
    emit('pageFullScreen');
  }

  // 在页面关闭或刷新之前，保存数据
  window.addEventListener('beforeunload', () => {
    storage.set(TABS_ROUTES, JSON.stringify(tabsList.value));
  });

  //删除tab
  function closeTabItem(fullPath) {
    const routeInfo = ref(tabsList.value.find((item) => item.fullPath == fullPath));
    removeTab(routeInfo);
  }

  //删除当前 tab
  function closeCurrentTabItem() {
    removeTab(currentRoute);
  }

  //tab 编辑
  const onEdit = (targetKey: string | MouseEvent) => {
    closeTabItem(targetKey);
  };

  function goPage(fullPath) {
    if (fullPath === route.fullPath) return;
    activeKey.value = fullPath;
    go(fullPath, true);
  }

  // 刷新页面
  async function reloadPage() {
    delKeepAliveCompName();
    const redo = useRedo(router);
    await redo();
  }

  // 关闭当前页面
  function removeTab(route) {
    tabsViewStore.closeCurrentTab(route);
    // 如果关闭的是当前页
    if (activeKey.value === route.value.fullPath) {
      const current = tabsList.value[Math.max(0, tabsList.value.length - 1)];
      activeKey.value = current.fullPath;
      router.push(current);
    }
  }

  // 关闭左侧
  function closeLeft() {
    tabsViewStore.closeLeftTabs(getCurrentTabRoute, activeKey.value);
    router.replace(route.fullPath);
  }

  // 关闭右侧
  function closeRight() {
    tabsViewStore.closeRightTabs(getCurrentTabRoute, activeKey.value);
    router.replace(route.fullPath);
  }

  // 关闭其他
  function closeOther() {
    tabsViewStore.closeOtherTabs(getCurrentTabRoute, activeKey.value);
    router.replace(route.fullPath);
  }

  // 关闭全部
  function closeAll() {
    tabsViewStore.closeAllTabs();
    router.replace(storage.get(FIRST_ROUTE));
    // router.replace(PageEnum.BASE_HOME_REDIRECT);
  }
</script>

<style lang="less" scoped>
  .tags-view {
    :deep(
        .ant-tabs.ant-tabs-card .ant-tabs-nav .ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab
      ) {
      height: 32px;
      line-height: 32px;
      border-radius: 3px;
      margin-right: 6px;
      cursor: pointer;
      position: relative;
      border: none;
    }
    :deep(.ant-tabs .ant-tabs-nav .ant-tabs-nav-more) {
      padding: 0 16px;
    }

    :deep(.ant-tabs .ant-tabs-nav .ant-tabs-tab-remove) {
      margin-left: 0;
    }

    :deep(.ant-tabs-bar) {
      margin-bottom: 0px;
    }
    .tabs-close {
      min-width: 32px;
      width: 32px;
      height: 32px;
      line-height: 32px;
      text-align: center;
      border-radius: 2px;
      cursor: pointer;
      //margin-right: 10px;

      &-btn {
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
  }
  .dark-tags-view {
    :deep(
        .ant-tabs.ant-tabs-card .ant-tabs-nav .ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab
      ) {
      background: #151515;
    }
    :deep(.ant-tabs-top > .ant-tabs-nav::before) {
      border: none;
    }
    .tabs-close {
      background: #151515;
    }
  }
</style>
