<template>
  <div
    v-if="visible"
    class="loading-overlay"
    :class="{
      'loading-overlay-fullscreen': fullscreen,
      'loading-overlay-inline': !fullscreen
    }"
    :style="containerStyle"
  >
    <div class="loading-hud" :class="{ 'loading-hud-inline': !fullscreen }">
      <div class="loading-spinner" :style="spinnerStyle">
        <svg class="loading-svg" viewBox="0 0 50 50">
          <circle
            class="loading-path"
            cx="25"
            cy="25"
            r="18"
            fill="none"
            stroke="currentColor"
            :stroke-width="strokeWidth"
            :stroke-linecap="strokeLinecap"
            stroke-dasharray="85 120"
            stroke-dashoffset="0"
          ></circle>
        </svg>
      </div>
      <div v-if="text" class="loading-text" :style="textStyle">{{ text }}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'

// 定义加载动画类型
type LoadingType = 'spinner' | 'dots' | 'pulse' | 'ring'

// Props 定义
const props = defineProps<{
  // 是否显示加载组件
  visible: boolean
  // 加载动画类型
  type?: LoadingType
  // 加载动画大小
  size?: number | string
  // 加载动画颜色
  color?: string
  // 是否全屏显示
  fullscreen?: boolean
  // 加载文本
  text?: string
  // 遮罩层背景色
  background?: string
  // 遮罩层透明度
  opacity?: number
  // 线条宽度（仅适用于spinner和ring类型）
  strokeWidth?: number
  // 线条末端样式（仅适用于spinner类型）
  strokeLinecap?: 'round' | 'butt' | 'square'
}>()

// 计算容器样式
const containerStyle = computed(() => {
  const style: any = {}
  if (props.fullscreen) {
    style.background =
      props.background ||
      'radial-gradient(circle at 20% 20%, rgba(255,247,249,0.75), rgba(255,236,240,0.72))'
    style.opacity = props.opacity ?? 1
  }
  return style
})

const spinnerStyle = computed(() => ({
  width: typeof props.size === 'number' ? `${props.size}px` : props.size || '44px',
  height: typeof props.size === 'number' ? `${props.size}px` : props.size || '44px',
  color: props.color || '#fff'
}))

// 计算线条宽度
const strokeWidth = computed(() => {
  return props.strokeWidth || 3
})

// 计算线条末端样式
const strokeLinecap = computed(() => {
  return props.strokeLinecap || 'round'
})

// 计算文本样式
const textStyle = computed(() => {
  return {
    marginTop: '12px',
    color: '#fff'
  }
})
</script>

<style scoped>
.loading-overlay-fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-overlay-inline {
  position: relative;
  display: inline-flex;
}

.loading-overlay {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  inset: 0;
  background: transparent;
}

.loading-hud {
  min-width: 100px;
  padding: 18px 22px;
  border-radius: 14px;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
  backdrop-filter: blur(6px);
}

.loading-hud-inline {
  position: absolute;
  top: 0;
  left: 0;
}

.loading-spinner {
  position: relative;
  display: inline-flex;
}

.loading-svg {
  animation: rotate 1s linear infinite;
  transform-origin: center center;
}

.loading-path {
  stroke: currentColor;
  stroke-linecap: round;
  animation: dash 1.5s ease-in-out infinite;
}

.loading-text {
  font-size: 14px;
  color: #fff;
  font-weight: 500;
  letter-spacing: 0.2px;
}

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

@keyframes dash {
  0% {
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dashoffset: -55;
  }
  100% {
    stroke-dashoffset: -170;
  }
}
</style>
