<template>
  <Teleport to="body">
    <Transition name="fade">
      <div v-if="visible" class="global-loading-overlay" @click.self="handleClick">
        <div class="global-loading-content">
          <div class="loading-spinner">
            <div class="spinner-ring"></div>
            <div class="spinner-ring"></div>
            <div class="spinner-ring"></div>
            <div class="spinner-ring"></div>
          </div>
          <div v-if="text" class="loading-text">{{ text }}</div>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script setup>
import { defineProps, defineEmits, watch, onUnmounted } from 'vue'

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  text: {
    type: String,
    default: ''
  },
  clickable: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['click'])

function handleClick() {
  if (props.clickable) {
    emit('click')
  }
}

// 禁用/启用页面滚动
function disableBodyScroll() {
  const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth
  document.body.classList.add('global-loading-no-scroll')
  // 如果有滚动条，使用 CSS 变量存储宽度，防止页面抖动
  if (scrollbarWidth > 0) {
    document.documentElement.style.setProperty('--global-loading-scrollbar-width', `${scrollbarWidth}px`)
  }
}

function enableBodyScroll() {
  document.body.classList.remove('global-loading-no-scroll')
  document.documentElement.style.removeProperty('--global-loading-scrollbar-width')
}

// 监听 visible 变化，控制页面滚动
watch(() => props.visible, (newVal) => {
  if (newVal) {
    disableBodyScroll()
  } else {
    enableBodyScroll()
  }
}, { immediate: true })

// 组件卸载时恢复滚动
onUnmounted(() => {
  enableBodyScroll()
})
</script>

<style scoped>
.global-loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
  z-index: 99999;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
}

.global-loading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
}

/* Loading 动画 */
.loading-spinner {
  position: relative;
  width: 64px;
  height: 64px;
}

.spinner-ring {
  position: absolute;
  width: 100%;
  height: 100%;
  border: 3px solid transparent;
  border-top-color: var(--color-primary, #3B82F6);
  border-radius: 50%;
  animation: spin 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}

.spinner-ring:nth-child(1) {
  animation-delay: -0.45s;
  border-top-color: var(--color-primary, #3B82F6);
  opacity: 1;
}

.spinner-ring:nth-child(2) {
  animation-delay: -0.3s;
  border-top-color: rgba(59, 130, 246, 0.8);
  opacity: 0.8;
  width: 80%;
  height: 80%;
  top: 10%;
  left: 10%;
}

.spinner-ring:nth-child(3) {
  animation-delay: -0.15s;
  border-top-color: rgba(59, 130, 246, 0.6);
  opacity: 0.6;
  width: 60%;
  height: 60%;
  top: 20%;
  left: 20%;
}

.spinner-ring:nth-child(4) {
  animation-delay: 0s;
  border-top-color: rgba(59, 130, 246, 0.4);
  opacity: 0.4;
  width: 40%;
  height: 40%;
  top: 30%;
  left: 30%;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.loading-text {
  color: var(--color-text, #F2F2F2);
  font-size: 14px;
  font-weight: 500;
  text-align: center;
  margin-top: 8px;
}

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

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

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

<style>
/* 全局样式：禁用页面滚动 */
body.global-loading-no-scroll {
  overflow: hidden !important;
  padding-right: var(--global-loading-scrollbar-width, 0);
}
</style>

