<script setup lang="ts">
import type { TabItem } from '@/stores/modules/tabbar';

import {
  ArrowDown,
  ArrowLeft,
  ArrowRight,
  Close,
  DArrowRight,
  Fold,
  FullScreen,
  Minus,
  Rank,
  Refresh,
  StarFilled,
  Unlock,
} from '@element-plus/icons-vue';
import { computed, onMounted, onUnmounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';

import { useTabbarStore } from '@/stores';

defineOptions({
  name: 'TabsView',
});

defineProps<{
  showIcon?: boolean;
}>();

const emit = defineEmits<{
  close: [path: string];
  unpin: [tab: TabItem];
}>();

const router = useRouter();
const route = useRoute();
const tabbarStore = useTabbarStore();

// 当前激活的标签页
const activeTabPath = computed(() => tabbarStore.activeTab);

// 标签页列表
const tabs = computed(() => tabbarStore.tabs);

// 全屏状态
const isFullscreen = ref(false);

// 右键菜单
const contextMenuVisible = ref(false);
const contextMenuStyle = ref({ left: '0px', top: '0px' });
const contextMenuTab = ref<TabItem | null>(null);

// 点击标签页
function handleTabClick(tab: TabItem) {
  if (route.path !== tab.path) {
    router.push(tab.path);
  }
}

// 关闭标签页
function handleTabClose(path: string) {
  emit('close', path);
}

// 固定/取消固定标签页
function handleUnpin(tab: TabItem) {
  emit('unpin', tab);
}

// 右键菜单
function handleContextMenu(e: MouseEvent, tab: TabItem) {
  e.preventDefault();
  e.stopPropagation();
  contextMenuTab.value = tab;
  contextMenuVisible.value = true;

  // 使用视口坐标定位（fixed），避免被父容器的 overflow 裁剪
  contextMenuStyle.value = {
    left: `${e.clientX}px`,
    top: `${e.clientY}px`,
  };
}

// 关闭右键菜单
function closeContextMenu() {
  contextMenuVisible.value = false;
  contextMenuTab.value = null;
}

// 点击外部关闭右键菜单
function handleClickOutside(e: MouseEvent) {
  if (contextMenuVisible.value) {
    closeContextMenu();
  }
}

onMounted(() => {
  document.addEventListener('click', handleClickOutside);
});

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside);
});

// 获取右键菜单项
interface ContextMenuItem {
  key: string;
  label: string;
  icon: any;
  disabled?: boolean;
  divider?: boolean;
}

const contextMenuItems = computed((): ContextMenuItem[] => {
  const tab = contextMenuTab.value;
  if (tab == null)
    return [];

  const tabIndex = tabs.value.findIndex(t => t.path === tab.path);
  const isCurrentTab = tab.path === activeTabPath.value;
  const hasLeftTabs = tabs.value.some((t, index) => index < tabIndex && !t.affix);
  const hasRightTabs = tabs.value.some((t, index) => index > tabIndex && !t.affix);
  const hasOtherTabs = tabs.value.length > (tab.affix ? 1 : 2);

  return [
    {
      key: 'close',
      label: '关闭',
      icon: Close,
      disabled: tab.affix || tabs.value.length <= 1,
    },
    {
      key: 'reload',
      label: '重新加载',
      icon: Refresh,
      disabled: !isCurrentTab,
    },
    {
      key: 'toggle-affix',
      label: tab.affix ? '取消固定' : '固定',
      icon: tab.affix ? Unlock : StarFilled,
      disabled: false,
    },
    { key: 'divider-1', label: '', icon: null, divider: true },
    {
      key: 'close-left',
      label: '关闭左侧',
      icon: ArrowLeft,
      disabled: !hasLeftTabs,
    },
    {
      key: 'close-right',
      label: '关闭右侧',
      icon: ArrowRight,
      disabled: !hasRightTabs,
    },
    { key: 'divider-2', label: '', icon: null, divider: true },
    {
      key: 'close-other',
      label: '关闭其它',
      icon: Fold,
      disabled: !hasOtherTabs,
    },
    {
      key: 'close-all',
      label: '关闭全部',
      icon: Rank,
      disabled: tabs.value.length <= (tab.affix ? 1 : 2),
    },
  ];
});

// 重新加载当前页面
function handleReload() {
  router.replace({ path: route.path, query: { _t: Date.now().toString() } });
}

// 处理右键菜单项点击
function handleContextMenuItem(item: ContextMenuItem) {
  if (item.disabled || contextMenuTab.value == null)
    return;

  const tab = contextMenuTab.value;

  switch (item.key) {
    case 'close':
      handleTabClose(tab.path);
      break;
    case 'reload':
      handleReload();
      break;
    case 'toggle-affix':
      tabbarStore.toggleAffixTab(tab.path);
      break;
    case 'close-left':
      tabbarStore.closeLeftTabs?.(tab.path);
      break;
    case 'close-right':
      tabbarStore.closeRightTabs(tab.path);
      break;
    case 'close-other':
      tabbarStore.closeOtherTabs(tab.path);
      break;
    case 'close-all':
      tabbarStore.closeAllTabs();
      break;
  }

  closeContextMenu();
}

// 切换全屏
function toggleFullscreen() {
  isFullscreen.value = !isFullscreen.value;
  if (isFullscreen.value) {
    document.documentElement.requestFullscreen();
  }
  else {
    document.exitFullscreen();
  }
}

// 更多操作菜单
const moreMenuItems = [
  {
    label: '关闭其他标签页',
    icon: Fold,
    command: 'closeOther',
  },
  {
    label: '关闭右侧标签页',
    icon: DArrowRight,
    command: 'closeRight',
  },
  {
    label: '关闭所有标签页',
    icon: Rank,
    command: 'closeAll',
  },
];

function handleMoreCommand(command: string) {
  switch (command) {
    case 'closeOther':
      tabbarStore.closeOtherTabs();
      break;
    case 'closeRight':
      tabbarStore.closeRightTabs();
      break;
    case 'closeAll':
      tabbarStore.closeAllTabs();
      break;
  }
}
</script>

<template>
  <div class="tabs-view">
    <div class="tabs-container">
      <div
        v-for="tab in tabs"
        :key="tab.path"
        class="tab-item" :class="[{ 'is-active': tab.path === activeTabPath, 'is-affix': tab.affix }]"
        @click="handleTabClick(tab)"
        @contextmenu="handleContextMenu($event, tab)"
      >
        <!-- 标签页内容 -->
        <div class="tab-content">
          <!-- 图标 -->
          <el-icon v-if="showIcon && tab.icon" class="tab-icon">
            <component :is="tab.icon" />
          </el-icon>

          <!-- 标题 -->
          <span class="tab-title">{{ tab.title }}</span>

          <!-- 固定图标 -->
          <el-icon
            v-if="tab.affix"
            class="tab-affix-icon"
            @click.stop="handleUnpin(tab)"
          >
            <StarFilled />
          </el-icon>

          <!-- 关闭按钮 -->
          <el-icon
            v-if="!tab.affix && tabs.length > 1"
            class="tab-close-icon"
            @click.stop="handleTabClose(tab.path)"
          >
            <Close />
          </el-icon>
        </div>
      </div>

      <!-- 右键菜单 -->
      <transition name="context-menu-fade">
        <div
          v-if="contextMenuVisible"
          class="context-menu"
          :style="contextMenuStyle"
        >
          <div
            v-for="item in contextMenuItems"
            :key="item.key"
            :class="[{ disabled: item.disabled, divider: item.divider }]"
            class="context-menu-item-element context-menu-item"
            @click="handleContextMenuItem(item)"
          >
            <template v-if="!item.divider">
              <el-icon class="context-menu-icon">
                <component :is="item.icon" />
              </el-icon>
              <span class="context-menu-label">{{ item.label }}</span>
            </template>
          </div>
        </div>
      </transition>
    </div>

    <!-- 工具栏 -->
    <div class="tabs-toolbar">
      <!-- 更多操作 -->
      <el-dropdown @command="handleMoreCommand">
        <div class="toolbar-btn">
          <el-icon><ArrowDown /></el-icon>
        </div>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item
              v-for="item in moreMenuItems"
              :key="item.label"
              :command="item.command"
            >
              <el-icon><component :is="item.icon" /></el-icon>
              <span>{{ item.label }}</span>
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>

      <!-- 全屏切换 -->
      <div class="toolbar-btn" @click="toggleFullscreen">
        <el-icon>
          <FullScreen v-if="!isFullscreen" />
          <Minus v-else />
        </el-icon>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.tabs-view {
  background-color: var(--el-bg-color);
  border-bottom: 1px solid var(--el-border-color-light);
  padding: 0 16px;
  height: 40px;
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
}

.tabs-container {
  display: flex;
  align-items: center;
  gap: 4px;
  overflow-x: auto;
  flex: 1;
  position: relative;

  &::-webkit-scrollbar {
    height: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background-color: var(--el-border-color-darker);
    border-radius: 3px;
  }

  &::-webkit-scrollbar-track {
    background-color: transparent;
  }
}

.tab-item {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 0 12px;
  height: 32px;
  background-color: var(--el-bg-color-page);
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
  user-select: none;
  white-space: nowrap;

  &:hover {
    background-color: var(--el-color-primary-light-9);
    .tab-close-icon {
      opacity: 1;
    }
  }

  &.is-active {
    background-color: var(--el-color-primary-light-8);
    color: var(--el-color-primary);
    font-weight: 500;

    .tab-close-icon {
      opacity: 1;
    }
  }

  &.is-affix {
    background-color: var(--el-color-warning-light-9);
  }
}

.tab-content {
  display: flex;
  align-items: center;
  gap: 8px;
}

.tab-icon {
  font-size: 16px;
}

.tab-title {
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tab-affix-icon {
  font-size: 14px;
  color: var(--el-color-warning);
  opacity: 0.8;
  cursor: pointer;
  transition: opacity 0.3s;

  &:hover {
    opacity: 1;
  }
}

.tab-close-icon {
  font-size: 14px;
  opacity: 0.6;
  cursor: pointer;
  transition: all 0.3s;
  border-radius: 50%;
  padding: 2px;

  &:hover {
    opacity: 1;
    background-color: var(--el-color-primary-light-7);
    color: var(--el-color-primary);
  }
}

.tabs-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-left: 12px;
  border-left: 1px solid var(--el-border-color-light);
}

.toolbar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  cursor: pointer;
  border-radius: 4px;
  transition: all 0.3s;

  &:hover {
    background-color: var(--el-fill-color-light);
    color: var(--el-color-primary);
  }

  .el-icon {
    font-size: 16px;
  }
}

// 右键菜单
.context-menu {
  position: fixed;
  z-index: 2000;
  background: #fff;
  border: 1px solid var(--el-border-color-light);
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  padding: 4px;
  min-width: 140px;
}

.context-menu-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
  font-size: 13px;
  color: var(--el-text-color-regular);

  &:hover:not(.disabled) {
    background-color: var(--el-color-primary-light-9);
    color: var(--el-color-primary);

    .context-menu-icon {
      color: var(--el-color-primary);
    }
  }

  &.disabled {
    cursor: not-allowed;
    opacity: 0.4;
  }

  &.divider {
    height: 1px;
    padding: 0;
    margin: 4px 8px;
    background-color: var(--el-border-color-light);
    cursor: default;

    &:hover {
      background-color: transparent;
    }
  }
}

.context-menu-icon {
  font-size: 14px;
  color: var(--el-text-color-secondary);
  transition: color 0.2s;
}

.context-menu-label {
  white-space: nowrap;
}

.context-menu-fade-enter-active,
.context-menu-fade-leave-active {
  transition: opacity 0.15s ease;
}

.context-menu-fade-enter-from,
.context-menu-fade-leave-to {
  opacity: 0;
}
</style>
