<template>
  <div class="tags-view-container"
    @mouseenter="hovered = true" @mouseleave="hovered = false">
    <div class="tags-view-wrapper" ref="scrollWrapperRef"
      @wheel.prevent="handleWheel"
      @scroll="onScroll">
      <div class="tags-view-scroll">
        <router-link
          v-for="tag in visitedViews"
          :key="tag.path"
          :class="isActive(tag) ? 'active-tag' : 'tag'"
          :to="{ path: tag.path, query: tag.query }"
          @contextmenu.prevent="openMenu($event, tag)"
        >
          <el-icon v-if="tag.meta.icon" class="tag-icon">
            <component :is="tag.meta.icon" />
          </el-icon>
          <span class="tag-title">{{ tag.meta.title }}</span>
          <el-icon 
            class="tag-close" 
            @click.prevent.stop="closeSelectedTag(tag)"
            v-if="!isAffix(tag)"
          >
            <close />
          </el-icon>
        </router-link>
      </div>
    </div>

    <div class="scroll-track" :class="{ visible: hovered && hasOverflow }">
      <div class="scroll-thumb" :style="thumbStyle" @mousedown="onThumbDown"></div>
    </div>
    
    <!-- 右键菜单 -->
    <ul v-show="visible" :style="{left: left+'px', top: top+'px'}" class="contextmenu">
      <li @click="refreshSelectedTag(selectedTag)">
        <el-icon><refresh /></el-icon>
        <span>刷新页面</span>
      </li>
      <li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">
        <el-icon><close /></el-icon>
        <span>关闭当前</span>
      </li>
      <li @click="closeOthersTags">
        <el-icon><circle-close /></el-icon>
        <span>关闭其他</span>
      </li>
      <li @click="closeLeftTags">
        <el-icon><back /></el-icon>
        <span>关闭左侧</span>
      </li>
      <li @click="closeRightTags">
        <el-icon><right /></el-icon>
        <span>关闭右侧</span>
      </li>
      <li @click="closeAllTags">
        <el-icon><remove /></el-icon>
        <span>关闭所有</span>
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Close, Refresh, CircleClose, Back, Right, Remove } from '@element-plus/icons-vue'
import { ElMessageBox } from 'element-plus'
import { useTagsViewStore } from '@/store/tagsViewStore'

const router = useRouter()
const route = useRoute()
const tagsViewStore = useTagsViewStore()

const visitedViews = computed(() => tagsViewStore.visitedViews)
const affixTags = computed(() => tagsViewStore.affixTags)

const visible = ref(false)
const top = ref(0)
const left = ref(0)
const selectedTag = ref({})

const initTags = () => {
  if (route.name) {
    tagsViewStore.addVisitedView(route)
  }
  const dashboardRoute = router.getRoutes().find(r => r.name === 'Dashboard')
  if (dashboardRoute) {
    if (!tagsViewStore.affixTags.some(tag => tag.path === dashboardRoute.path)) {
       tagsViewStore.affixTags.push(dashboardRoute)
    }
    tagsViewStore.addVisitedView(dashboardRoute)
  }
}

const refreshSelectedTag = (view) => {
  const { fullPath } = view
  router.replace('/redirect' + fullPath)
}

const closeSelectedTag = (view) => {
  tagsViewStore.delVisitedView(view).then((visitedViews) => {
    if (isActive(view)) {
      toLastView(visitedViews, view)
    }
  })
}

const closeOthersTags = () => {
  router.push(selectedTag.value)
  tagsViewStore.delOthersViews(selectedTag.value)
}

const closeLeftTags = () => {
  tagsViewStore.delLeftViews(selectedTag.value).then((visitedViews) => {
    if (!visitedViews.find(i => i.path === route.path)) {
      toLastView(visitedViews)
    }
  })
}

const closeRightTags = () => {
  tagsViewStore.delRightViews(selectedTag.value).then((visitedViews) => {
    if (!visitedViews.find(i => i.path === route.path)) {
      toLastView(visitedViews)
    }
  })
}

const closeAllTags = () => {
  tagsViewStore.delAllViews().then((visitedViews) => {
    toLastView(visitedViews)
  })
}

const toLastView = (visitedViews, view) => {
  const latestView = visitedViews.slice(-1)[0]
  if (latestView) {
    router.push(latestView)
  } else {
    if (view && view.name === 'Dashboard') {
      router.push('/redirect' + '/dashboard')
    } else {
      router.push('/')
    }
  }
}

const isActive = (tag) => {
  return tag.path === route.path
}

const isAffix = (tag) => {
  return tag.meta && tag.meta.affix
}

const openMenu = (e, tag) => {
  const menuMinWidth = 125
  const offsetLeft = e.clientX
  const offsetWidth = document.body.clientWidth
  const maxLeft = offsetWidth - menuMinWidth
  
  left.value = offsetLeft > maxLeft ? maxLeft : offsetLeft
  top.value = e.clientY
  
  visible.value = true
  selectedTag.value = tag
}

// ---- 滚动 & 滚动条 ----
const scrollWrapperRef = ref(null)
const hovered = ref(false)
const hasOverflow = ref(false)
const thumbStyle = ref({ width: '0px', left: '0px' })

const handleWheel = (e) => {
  if (scrollWrapperRef.value) {
    scrollWrapperRef.value.scrollLeft += e.deltaY || e.deltaX
  }
}

const refreshState = () => {
  const el = scrollWrapperRef.value
  if (!el) return

  const { scrollLeft, scrollWidth, clientWidth } = el
  const maxScroll = scrollWidth - clientWidth
  hasOverflow.value = maxScroll > 1

  if (!hasOverflow.value) {
    thumbStyle.value = { width: '0px', left: '0px' }
    return
  }

  const trackWidth = clientWidth
  const thumbW = Math.max((clientWidth / scrollWidth) * trackWidth, 30)
  const scrollRatio = maxScroll > 0 ? scrollLeft / maxScroll : 0
  const thumbLeft = scrollRatio * (trackWidth - thumbW)
  thumbStyle.value = { width: thumbW + 'px', left: thumbLeft + 'px' }
}

const onScroll = () => {
  refreshState()
}

const scrollToActiveTag = () => {
  const el = scrollWrapperRef.value
  if (!el) return
  const activeEl = el.querySelector('.active-tag')
  if (!activeEl) return
  const wrapperRect = el.getBoundingClientRect()
  const tagRect = activeEl.getBoundingClientRect()
  if (tagRect.left < wrapperRect.left + 28) {
    el.scrollLeft -= (wrapperRect.left + 28 - tagRect.left + 12)
  } else if (tagRect.right > wrapperRect.right - 28) {
    el.scrollLeft += (tagRect.right - wrapperRect.right + 28 + 12)
  }
}

const onThumbDown = (e) => {
  e.preventDefault()
  const el = scrollWrapperRef.value
  if (!el) return
  const startX = e.clientX
  const startScroll = el.scrollLeft
  const maxScroll = el.scrollWidth - el.clientWidth
  const trackWidth = el.clientWidth
  const thumbW = Math.max((el.clientWidth / el.scrollWidth) * trackWidth, 30)
  const movable = trackWidth - thumbW

  const onMove = (ev) => {
    const dx = ev.clientX - startX
    const scrollDelta = movable > 0 ? (dx / movable) * maxScroll : 0
    el.scrollLeft = Math.min(Math.max(startScroll + scrollDelta, 0), maxScroll)
  }
  const onUp = () => {
    document.removeEventListener('mousemove', onMove)
    document.removeEventListener('mouseup', onUp)
  }
  document.addEventListener('mousemove', onMove)
  document.addEventListener('mouseup', onUp)
}

watch(visitedViews, () => nextTick(() => { refreshState(); scrollToActiveTag() }), { deep: true })

const closeMenu = () => {
  visible.value = false
}

watch(route, (newRoute) => {
  if (newRoute.name) {
    tagsViewStore.addVisitedView(newRoute)
  }
  nextTick(scrollToActiveTag)
})

const handleClickOutside = () => {
  closeMenu()
}

const onResize = () => {
  refreshState()
  scrollToActiveTag()
}

onMounted(() => {
  initTags()
  document.addEventListener('click', handleClickOutside)
  nextTick(() => { refreshState(); scrollToActiveTag() })
  window.addEventListener('resize', onResize)
})

onBeforeUnmount(() => {
  document.removeEventListener('click', handleClickOutside)
  window.removeEventListener('resize', onResize)
})
</script>

<style scoped>
.tags-view-container {
  height: 40px;
  width: 100%;
  background-color: #ffffff;
  border-bottom: 1px solid #e1e8ed;
  z-index: 10;
  display: flex;
  align-items: stretch;
  position: relative;
  overflow: hidden;
}

/* 标签滚动区域 */
.tags-view-wrapper {
  flex: 1;
  min-width: 0;
  height: 100%;
  overflow-x: scroll;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.tags-view-wrapper::-webkit-scrollbar {
  display: none;
}

.tags-view-scroll {
  display: inline-flex;
  align-items: center;
  height: 100%;
  padding: 0 8px;
  gap: 4px;
}

/* 底部自定义滚动条（在容器上，不在滚动区域内） */
.scroll-track {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  opacity: 0;
  transition: opacity 0.25s;
  pointer-events: none;
  z-index: 5;
}

.scroll-track.visible {
  opacity: 1;
  pointer-events: auto;
}

.scroll-thumb {
  position: absolute;
  top: 0;
  height: 100%;
  border-radius: 3px;
  background: rgba(180,188,199,0.45);
  transition: background 0.15s;
  cursor: pointer;
}

.scroll-thumb:hover {
  background: rgba(180,188,199,0.65);
}

/* 标签样式 */
.tag, .active-tag {
  height: 32px;
  display: inline-flex;
  align-items: center;
  padding: 0 12px;
  border-radius: 0;
  font-size: 13px;
  text-decoration: none;
  position: relative;
  transition: all 0.2s ease;
  border: 1px solid transparent;
  border-bottom: none;
  flex-shrink: 0;
  white-space: nowrap;
}

.tag {
  color: #7f8c8d;
  background-color: #f8f9fa;
}

.tag:hover {
  color: #34495e;
  background-color: #e8ecf0;
}

.active-tag {
  color: #2c3e50;
  background-color: #ffffff;
  border: 1px solid #e1e8ed;
  border-bottom: 2px solid #2c3e50;
  font-weight: 500;
}

.tag-icon {
  margin-right: 6px;
  width: 14px;
  height: 14px;
  color: #95a5a6;
  transition: color 0.2s ease;
}

.tag:hover .tag-icon {
  color: #34495e;
}

.active-tag .tag-icon {
  color: #2c3e50;
}

.tag-title {
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tag-close {
  margin-left: 8px;
  width: 16px;
  height: 16px;
  border-radius: 0;
  transition: all 0.2s ease;
  color: #95a5a6;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2px;
}

.tag-close:hover {
  color: #e74c3c;
  background-color: rgba(231, 76, 60, 0.1);
}

.tag:hover .tag-close {
  color: #7f8c8d;
}

.active-tag .tag-close {
  color: #7f8c8d;
}

.active-tag .tag-close:hover {
  color: #e74c3c;
  background-color: rgba(231, 76, 60, 0.1);
}

/* 右键菜单 */
.contextmenu {
  position: fixed;
  z-index: 100;
  background-color: #ffffff;
  list-style-type: none;
  padding: 4px 0;
  border-radius: 0;
  box-shadow: 0 2px 8px rgba(44, 62, 80, 0.1);
  font-size: 12px;
  border: 1px solid #e1e8ed;
}

.contextmenu li {
  padding: 8px 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  color: #34495e;
  transition: all 0.2s ease;
}

.contextmenu li:hover {
  background-color: #f8f9fa;
  color: #2c3e50;
}

.contextmenu li .el-icon {
  margin-right: 8px;
  font-size: 14px;
  color: #7f8c8d;
}

.contextmenu li:hover .el-icon {
  color: #2c3e50;
}
</style>
