<template>
  <transition name="back-to-top-fade">
    <div
      v-if="visible"
      class="back-to-top-btn"
      role="button"
      tabindex="0"
      :aria-label="t('Back to top')"
      :title="t('Back to top')"
      @click="scrollToTop"
      @keydown.enter="scrollToTop"
      @keydown.space.prevent="scrollToTop"
    >
      <!-- SVG 圆形进度条 -->
      <svg class="progress-ring" viewBox="0 0 48 48">
        <!-- 背景圆圈（灰色） -->
        <circle
          class="progress-ring-bg"
          cx="24"
          cy="24"
          r="23"
          fill="none"
          stroke="#d1d5db"
          stroke-width="2"
        />
        <!-- 进度圆圈（绿色） -->
        <circle
          class="progress-ring-progress"
          cx="24"
          cy="24"
          r="23"
          fill="none"
          stroke="#22c55e"
          stroke-width="2"
          stroke-linecap="round"
          :stroke-dasharray="circumference"
          :stroke-dashoffset="progressOffset"
        />
      </svg>
      <!-- 箭头图标 -->
      <Icon icon="tabler:arrow-up" :width="20" :height="20" class="arrow-icon" />
    </div>
  </transition>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { Icon } from '@iconify/vue'
import { t } from '@/shared/i18n'

// 显示/隐藏状态
const visible = ref(false)

// 滚动阈值（滚动超过多少像素后显示按钮）
const SCROLL_THRESHOLD = 300

// 滚动进度（0-1）
const scrollProgress = ref(0)

// 存储已注册的滚动容器，用于清理
const registeredContainers = ref<(Element | Window)[]>([])

// SVG 圆形进度条的半径
const radius = 23
const circumference = computed(() => 2 * Math.PI * radius)

// 进度条偏移量（用于显示进度）
const progressOffset = computed(() => {
  return circumference.value * (1 - scrollProgress.value)
})

// 找到所有可能的滚动容器
const findScrollContainers = (): (Element | Window)[] => {
  const containers: (Element | Window)[] = [window]
  
  // 查找 .content-wrapper 容器
  const contentWrapper = document.querySelector('.content-wrapper')
  if (contentWrapper) {
    containers.push(contentWrapper)
  }
  
  // 查找其他可能的滚动容器
  const scrollableElements = document.querySelectorAll('[class*="scroll"], [class*="content"], [class*="wrapper"]')
  scrollableElements.forEach(el => {
    const style = window.getComputedStyle(el)
    if (style.overflowY === 'auto' || style.overflowY === 'scroll' || 
        style.overflow === 'auto' || style.overflow === 'scroll') {
      if (!containers.includes(el)) {
        containers.push(el)
      }
    }
  })
  
  return containers
}

// 获取容器的滚动高度信息
const getScrollInfo = (container: Element | Window): { scrollTop: number; scrollHeight: number; clientHeight: number } => {
  if (container === window) {
    return {
      scrollTop: window.pageYOffset || document.documentElement.scrollTop || 0,
      scrollHeight: document.documentElement.scrollHeight || document.body.scrollHeight || 0,
      clientHeight: window.innerHeight || document.documentElement.clientHeight || 0
    }
  } else {
    const el = container as Element
    return {
      scrollTop: el.scrollTop || 0,
      scrollHeight: el.scrollHeight || 0,
      clientHeight: el.clientHeight || 0
    }
  }
}

// 滚动到顶部
const scrollToTop = () => {
  const containers = registeredContainers.value
  
  containers.forEach(container => {
    if (container === window) {
      window.scrollTo({
        top: 0,
        behavior: 'smooth'
      })
    } else {
      const el = container as Element
      el.scrollTo({
        top: 0,
        behavior: 'smooth'
      })
    }
  })
}

// 使用 requestAnimationFrame 优化滚动处理性能
let rafId: number | null = null

// 处理滚动事件
const handleScroll = () => {
  // 使用 requestAnimationFrame 节流，避免过度计算
  if (rafId !== null) {
    return
  }
  
  rafId = requestAnimationFrame(() => {
    const containers = registeredContainers.value
    
    if (containers.length === 0) {
      rafId = null
      return
    }
    
    // 检查所有容器，取最大滚动值和总高度
    let maxScrollTop = 0
    let maxProgress = 0
    
    containers.forEach(container => {
      const info = getScrollInfo(container)
      const scrollTop = info.scrollTop
      const maxScroll = info.scrollHeight - info.clientHeight
      
      if (scrollTop > maxScrollTop) {
        maxScrollTop = scrollTop
      }
      
      // 计算当前容器的滚动进度
      if (maxScroll > 0) {
        const progress = Math.min(scrollTop / maxScroll, 1)
        if (progress > maxProgress) {
          maxProgress = progress
        }
      }
    })
    
    // 更新滚动进度
    scrollProgress.value = maxProgress
    
    // 根据最大滚动值判断是否显示按钮
    visible.value = maxScrollTop > SCROLL_THRESHOLD
    
    rafId = null
  })
}

onMounted(() => {
  // 延迟查找容器，确保 DOM 已渲染
  nextTick(() => {
    const containers = findScrollContainers()
    
    // 保存容器引用
    registeredContainers.value = containers
    
    // 为所有容器添加滚动监听
    containers.forEach(container => {
      container.addEventListener('scroll', handleScroll, { passive: true })
    })
    
    // 初始检查
    handleScroll()
  })
})

onUnmounted(() => {
  // 清理所有滚动监听器
  registeredContainers.value.forEach(container => {
    container.removeEventListener('scroll', handleScroll)
  })
  registeredContainers.value = []
  
  // 取消待处理的 requestAnimationFrame
  if (rafId !== null) {
    cancelAnimationFrame(rafId)
    rafId = null
  }
})
</script>

<style scoped>
.back-to-top-btn {
  position: fixed;
  right: 32px;
  bottom: 24px;
  z-index: 1000;
  width: 48px;
  height: 48px;
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.back-to-top-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

.back-to-top-btn:focus {
  outline: 2px solid #22c55e;
  outline-offset: 2px;
}

.back-to-top-btn:focus:not(:focus-visible) {
  outline: none;
}

.progress-ring {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
  pointer-events: none;
}

.progress-ring-progress {
  transition: stroke-dashoffset 0.1s linear;
}

.arrow-icon {
  position: relative;
  z-index: 1;
  color: #22c55e;
  transition: color 0.3s ease;
}

/* 移动端调整位置 */
@media (max-width: 768px) {
  .back-to-top-btn {
    right: 20px;
    bottom: 16px;
    width: 48px;
    height: 48px;
  }
  
  .arrow-icon {
    width: 18px;
    height: 18px;
  }
}

/* 淡入淡出动画 */
.back-to-top-fade-enter-active,
.back-to-top-fade-leave-active {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.back-to-top-fade-enter-from,
.back-to-top-fade-leave-to {
  opacity: 0;
  transform: scale(0.8) translateY(10px);
}

.back-to-top-fade-enter-to,
.back-to-top-fade-leave-from {
  opacity: 1;
  transform: scale(1) translateY(0);
}
</style>
