<template>
  <div class="header-tabs">
    <!-- 标签页容器 -->
    <el-tabs class="w-full flex-1" type="card" :model-value="activeTabPath" @tab-change="handleTabChange">
      <el-tab-pane v-for="tab in tabs" :key="tab.fullPath" :label="tab.title" :name="tab.fullPath">
        <template #label>
          <div
            class="w-full h-full px-3 flex items-center"
            @contextmenu="(event) => handleContextMenu(event, tab.fullPath)"
          >
            <icon :name="tab.icon" :size="16" :type="tab.iconType" v-if="tab?.icon" />
            <span class="text-base ml-1 mr-2">{{ tab.title }}</span>
            <div class="flex items-center" v-if="tabs.length > 1">
              <icon name="fixed" :size="14" :type="2" @click.stop="toggleTabFixed(tab.fullPath)" v-if="tab.fixed" />
              <el-icon :size="14" @click.stop="closeTab(tab.fullPath)" v-else><Close /></el-icon>
            </div>
          </div>
        </template>
      </el-tab-pane>
    </el-tabs>
    <!-- 右键菜单 -->
    <el-dropdown
      ref="dropdownRef"
      :virtual-ref="triggerRef"
      :show-arrow="false"
      :popper-options="popperOptions"
      virtual-triggering
      trigger="contextmenu"
      placement="bottom-start"
      popper-class="min-w-[120px]"
      @command="handleMenuCommand"
    >
      <template #dropdown>
        <el-dropdown-menu>
          <el-dropdown-item command="refresh">
            <icon class="mr-1" name="RefreshRight" :size="16" />
            <span>刷新页面</span>
          </el-dropdown-item>
          <el-dropdown-item command="toggleFixed" :disabled="isOnlyOneTab">
            <icon class="mr-1" :name="isRightClickedTabFixed ? 'unfixed' : 'fixed'" :size="16" :type="2" />
            <span>{{ isRightClickedTabFixed ? '取消固定' : '固定标签' }}</span>
          </el-dropdown-item>
          <el-dropdown-item command="close" :disabled="isRightClickedTabFixed || shouldDisableAllCloseButtons" divided>
            <icon class="mr-1" name="Close" :size="16" />
            <span>关闭</span>
          </el-dropdown-item>
          <el-dropdown-item command="closeLeft" :disabled="!hasClosableLeftTabs || shouldDisableAllCloseButtons">
            <icon class="mr-1" name="Back" :size="16" />
            <span>关闭左侧</span>
          </el-dropdown-item>
          <el-dropdown-item command="closeRight" :disabled="!hasClosableRightTabs || shouldDisableAllCloseButtons">
            <icon class="mr-1" name="Right" :size="16" />
            <span>关闭右侧</span>
          </el-dropdown-item>
          <el-dropdown-item command="closeOther" :disabled="!hasClosableOtherTabs || shouldDisableAllCloseButtons">
            <icon class="mr-1" name="close-other" :size="16" :type="2" />
            <span>关闭其他</span>
          </el-dropdown-item>
          <el-dropdown-item command="closeAll" :disabled="shouldDisableAllCloseButtons">
            <icon class="mr-1" name="Minus" :size="16" />
            <span>关闭全部</span>
          </el-dropdown-item>
        </el-dropdown-menu>
      </template>
    </el-dropdown>
  </div>
</template>

<script setup lang="ts">
import type { DropdownInstance } from 'element-plus'
import useTabsStore, { getRouteParamsFromTab } from '@/stores/modules/tabs'
import { useConfigStore } from '@/stores/modules/config'

// 实例和状态
const router = useRouter()
const route = useRoute()
const tabsStore = useTabsStore()
const configStore = useConfigStore()
const dropdownRef = ref<DropdownInstance>()
const menuPosition = ref<DOMRect>(new DOMRect(0, 0, 0, 0))
const triggerRef = ref({
  getBoundingClientRect: () => menuPosition.value
})
const rightClickedTabPath = ref<string>(route.fullPath)
const popperOptions = {
  modifiers: [{ name: 'offset', options: { offset: [0, 0] } }]
}
const tabs = computed(() => tabsStore.tabList)
const activeTabPath = computed(() => route.fullPath)
const isRightClickedTabFixed = computed(() => {
  const rightClickedTab = tabsStore.tabMap[rightClickedTabPath.value]
  return rightClickedTab?.fixed || false
})
const rightClickedTabIndex = computed(() => {
  return tabs.value.findIndex((tab) => tab.fullPath === rightClickedTabPath.value)
})
const isOnlyOneTab = computed(() => {
  return tabs.value.length === 1
})
const isFirstTab = computed(() => {
  return rightClickedTabIndex.value === 0
})
const isLastTab = computed(() => {
  return rightClickedTabIndex.value === tabs.value.length - 1
})
const closableTabCount = computed(() => {
  return tabs.value.filter((tab) => !tab.fixed).length
})
const shouldDisableAllCloseButtons = computed(() => {
  return isOnlyOneTab.value || closableTabCount.value === 0
})
const hasClosableLeftTabs = computed(() => {
  if (isFirstTab.value) return false
  const leftTabs = tabs.value.slice(0, rightClickedTabIndex.value)
  return leftTabs.some((tab) => !tab.fixed)
})
const hasClosableRightTabs = computed(() => {
  if (isLastTab.value) return false
  const rightTabs = tabs.value.slice(rightClickedTabIndex.value + 1)
  return rightTabs.some((tab) => !tab.fixed)
})
const hasClosableOtherTabs = computed(() => {
  return tabs.value.some((tab) => tab.fullPath !== rightClickedTabPath.value && !tab.fixed)
})

watch(
  route,
  () => {
    tabsStore.addTab()
  },
  { immediate: true }
)

// 标签页切换处理
const handleTabChange = (fullPath: string | number) => {
  const tabItem = tabsStore.tabMap[String(fullPath)]
  if (tabItem) {
    router.push(getRouteParamsFromTab(tabItem))
  }
}
// 右键菜单打开处理
const handleContextMenu = (event: MouseEvent, tabFullPath?: string) => {
  event.preventDefault()
  const { clientX, clientY } = event
  menuPosition.value = new DOMRect(clientX, clientY, 0, 0)
  rightClickedTabPath.value = tabFullPath || route.fullPath
  dropdownRef.value?.handleOpen()
}
// 右键菜单命令处理
const handleMenuCommand = (command: string) => {
  switch (command) {
    case 'refresh':
      // 刷新页面
      configStore.refreshRouterView()
      break
    case 'close':
      // 关闭标签页
      closeTab(rightClickedTabPath.value)
      break
    case 'closeLeft':
      // 关闭左侧标签
      tabsStore.closeLeftTabs(rightClickedTabPath.value)
      break
    case 'closeRight':
      // 关闭右侧标签
      tabsStore.closeRightTabs(rightClickedTabPath.value)
      break
    case 'closeOther':
      // 从关闭其他标签
      tabsStore.closeOtherTabs(rightClickedTabPath.value)
      break
    case 'closeAll':
      // 关闭全部标签页
      tabsStore.closeAllTabs()
      break
    case 'toggleFixed':
      // 切换固定状态
      toggleTabFixed(rightClickedTabPath.value)
      break
  }
}
// 切换标签页固定状态
const toggleTabFixed = (fullPath: string) => {
  tabsStore.toggleTabFixed(fullPath)
}
// 关闭指定标签页
const closeTab = (fullPath: string) => {
  tabsStore.closeTab(fullPath)
}
</script>

<style lang="scss" scoped>
.header-tabs {
  @apply border-t border-br mt-[-1px] px-4 flex bg-body;

  :deep(.el-tabs) {
    .el-tabs__header {
      margin-bottom: 0;
      border-bottom: none;

      .el-tabs__nav-next,
      .el-tabs__nav-prev {
        font-size: var(--el-font-size-large);
      }

      .el-tabs__nav {
        border: none;
        gap: 4px;
        height: 40px;
        padding: 4px 0;

        .el-tabs__item {
          border: 1px solid var(--el-border-color);
          border-radius: 5px;
          padding: 0;
          height: 100%;
          transition: none;

          &:hover {
            background-color: var(--menu-hover-bg-color);
            border-color: var(--menu-hover-br-color);
            color: var(--menu-hover-text-color);
          }

          &.is-active {
            background-color: var(--menu-active-bg-color);
            border-color: var(--menu-active-br-color);
            color: var(--menu-active-text-color);
          }
        }
      }
    }

    .el-tabs__content {
      display: none;
    }
  }
}
</style>
