<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { gameApi, type InitStatusDTO } from '../api/game'

const props = defineProps<{
  status: InitStatusDTO | null
}>()

// 阶段文案（鬼谷八荒风格）
const phaseTexts: Record<string, string | string[]> = {
  'scanning_assets': '扫描天地资源',
  'loading_map': '构建洪荒山川',
  'initializing_sects': '宗门入世',
  'generating_avatars': '众修士降临',
  'checking_llm': '连通天道意志',
  'generating_initial_events': [
    '天道轮转，命运初显',
    '因果交织，机缘暗涌',
    '气运流转，风云将起',
    '众生沉浮，天机莫测',
    '劫数将至，各凭造化',
    '红尘万丈，道心初定',
    '缘起缘灭，皆是天意',
    '大道无形，万法归一',
  ],
  'loading_save': '读取前世因果',
  'parsing_data': '解析天地法则',
  'restoring_state': '恢复时空位面',
  'finalizing': '万象归位',
  'complete': '天地初开',
  '': '混沌初始',
}

// 用于 generating_initial_events 阶段的轮换文案。
const eventPhaseTextIndex = ref(0)

// Tips 列表
const tips = [
  '修改角色目标，可以改变该角色的行事风格',
  '角色的性格特质，会极大影响角色的行事风格',
  '在符合角色灵根的洞府修行，事半功倍',
  '天灵根角色在任何洞府修行，都事半功倍',
  '改变天地灵机，不仅会影响加成，还会微妙调整角色行事风格',
  '偶尔会有修仙小说中的主角穿越进此方世界',
  '每个角色都有自己的思考和情绪',
  '除了修炼，炼丹和练气也很重要',
  '参加拍卖会可能捡漏，但要小心恶人的衔尾追杀',
  '江湖同道会根据你的行为取一个绰号',
  '双修虽好，还请克制',
  '在宗门驻地回血，可以回满HP',
  '境界之间，战力差距极大，越阶挑战难于登天',
  '天命之子特质的角色，好运连连，奇遇不断',
  '现代世界的穿越者，只想回到现实世界，但这是不可能的',
  '丹药有生效的时间限制',
  '由于大模型需要思考，游戏启动可能耗时较久',
]

const currentTip = ref(tips[Math.floor(Math.random() * tips.length)])
const displayProgress = ref(0) // 实际显示的进度
const localElapsed = ref(0)
let tipInterval: ReturnType<typeof setInterval> | null = null
let elapsedInterval: ReturnType<typeof setInterval> | null = null

const progress = computed(() => displayProgress.value)
const phaseText = computed(() => {
  const phaseName = props.status?.phase_name || ''
  const text = phaseTexts[phaseName] || phaseTexts['']
  if (Array.isArray(text)) {
    return text[eventPhaseTextIndex.value % text.length]
  }
  return text
})
const isError = computed(() => props.status?.status === 'error')
const errorMessage = computed(() => props.status?.error || '未知错误')

// 监听后端进度，如果后端进度领先，则同步
watch(() => props.status?.progress, (newVal) => {
  if (newVal !== undefined && newVal !== null) {
    if (newVal > displayProgress.value) {
      displayProgress.value = newVal
    }
  }
}, { immediate: true })

// 根据时间计算背景透明度：前5秒保持不透明，5-20秒逐渐透明到0.8。
// 只影响背景，不影响内容亮度。
const bgOpacity = computed(() => {
  const elapsed = localElapsed.value
  if (elapsed <= 5) return 1
  if (elapsed >= 20) return 0.8
  // 5秒 -> 1.0, 20秒 -> 0.8 (线性插值)。
  return 1 - (elapsed - 5) / 15 * 0.2
})

// SVG 圆环参数
const radius = 90
const circumference = 2 * Math.PI * radius
const strokeDashoffset = computed(() => {
  return circumference - (progress.value / 100) * circumference
})

async function handleRetry() {
  localElapsed.value = 0
  displayProgress.value = 0
  try {
    await gameApi.reinitGame()
  } catch (e: any) {
    console.error('Reinit failed:', e)
  }
}

function startTimers() {
  // Tips 切换
  tipInterval = setInterval(() => {
    const idx = Math.floor(Math.random() * tips.length)
    currentTip.value = tips[idx]
  }, 5000)
  
  // 本地计时器 + 阶段文案轮换 + 伪进度自增
  elapsedInterval = setInterval(() => {
    localElapsed.value++

    // 伪进度逻辑
    if (props.status?.status === 'in_progress' && displayProgress.value < 99) {
      const currentPhase = props.status?.phase ?? 0
      // 后端定义的进度节点: {0: 0, 1: 17, 2: 33, 3: 50, 4: 67, 5: 83}
      const progressMap: Record<number, number> = { 0: 0, 1: 17, 2: 33, 3: 50, 4: 67, 5: 83 }
      const nextPhaseStart = progressMap[currentPhase + 1] ?? 100
      
      // 每1秒增加 1%
      if (localElapsed.value % 1 === 0) {
        // 如果还没达到下一阶段的起点前 1%，就继续自增
        if (displayProgress.value < nextPhaseStart - 1) {
          displayProgress.value++
        } else if (currentPhase === 5 && displayProgress.value < 99) {
          // 最后一个阶段（5阶段）允许一直增加到 99%
          displayProgress.value++
        }
      }
    }

    // 每 5 秒切换一次 generating_initial_events 的文案。
    if (localElapsed.value % 5 === 0) {
      eventPhaseTextIndex.value++
    }
  }, 1000)
}

function stopTimers() {
  if (tipInterval) {
    clearInterval(tipInterval)
    tipInterval = null
  }
  if (elapsedInterval) {
    clearInterval(elapsedInterval)
    elapsedInterval = null
  }
}

// 当状态从 ready 变成其他时，重置
watch(() => props.status?.status, (newStatus, oldStatus) => {
  if (oldStatus === 'ready' && newStatus !== 'ready') {
    localElapsed.value = 0
    displayProgress.value = 0
  }
})

onMounted(() => {
  startTimers()
})

onUnmounted(() => {
  stopTimers()
})
</script>

<template>
  <div class="loading-overlay">
    <!-- 背景层 - 只有这层透明度变化 -->
    <div 
      class="bg-layer"
      :style="{ opacity: bgOpacity }"
    ></div>

    <!-- 背景装饰 -->
    <div class="bg-decoration" :style="{ opacity: bgOpacity }">
      <div class="glow glow-1"></div>
      <div class="glow glow-2"></div>
    </div>

    <!-- 主内容 -->
    <div class="content">
      <!-- 标题 -->
      <h1 class="title">AI 修仙世界模拟器</h1>
      <p class="subtitle">AI Cultivation World Simulator</p>

      <!-- 进度圆环 -->
      <div class="progress-ring">
        <svg width="220" height="220" viewBox="0 0 220 220">
          <defs>
            <linearGradient id="progress-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
              <stop offset="0%" style="stop-color:#00d4ff;stop-opacity:1" />
              <stop offset="100%" style="stop-color:#00ffa3;stop-opacity:1" />
            </linearGradient>
            <filter id="glow">
              <feGaussianBlur stdDeviation="3" result="coloredBlur"/>
              <feMerge>
                <feMergeNode in="coloredBlur"/>
                <feMergeNode in="SourceGraphic"/>
              </feMerge>
            </filter>
          </defs>
          <!-- 背景圆环 -->
          <circle
            class="track"
            cx="110"
            cy="110"
            :r="radius"
          />
          <!-- 进度圆环 -->
          <circle
            class="progress"
            :class="{ error: isError }"
            cx="110"
            cy="110"
            :r="radius"
            :stroke-dasharray="circumference"
            :stroke-dashoffset="strokeDashoffset"
            filter="url(#glow)"
          />
        </svg>
        
        <!-- 圆环内容 -->
        <div class="ring-content">
          <div class="percentage" :class="{ error: isError }">
            {{ isError ? '!' : progress + '%' }}
          </div>
          <div class="phase-text">{{ isError ? '初始化失败' : phaseText }}</div>
        </div>
      </div>

      <!-- 错误信息 -->
      <div v-if="isError" class="error-section">
        <p class="error-message">{{ errorMessage }}</p>
        <button class="retry-btn" @click="handleRetry">
          重新初始化
        </button>
      </div>

      <!-- Tips -->
      <div v-else class="tips-section">
        <div class="tips-label">修行小贴士</div>
        <div class="tips">{{ currentTip }}</div>
      </div>
    </div>

    <!-- 底部信息 -->
    <div class="footer">
      <div class="elapsed">已等待 {{ localElapsed }} 秒</div>
      <div class="version">v1.1.0</div>
    </div>
  </div>
</template>

<style scoped>
.loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* 背景层 - 只有这层会变透明，带模糊效果 */
.bg-layer {
  position: absolute;
  inset: 0;
  background: rgba(10, 10, 18, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: opacity 0.5s ease;
}

/* 背景装饰 */
.bg-decoration {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  opacity: 0.15;
}

.glow-1 {
  width: 400px;
  height: 400px;
  background: #00d4ff;
  top: 10%;
  left: 20%;
  animation: float 8s ease-in-out infinite;
}

.glow-2 {
  width: 300px;
  height: 300px;
  background: #00ffa3;
  bottom: 20%;
  right: 15%;
  animation: float 6s ease-in-out infinite reverse;
}

@keyframes float {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(30px, -20px); }
}

/* 主内容 */
.content {
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 1;
}

.title {
  font-size: 42px;
  font-weight: 300;
  letter-spacing: 16px;
  margin: 0 0 8px 16px;
  background: linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.8) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.subtitle {
  font-size: 12px;
  letter-spacing: 4px;
  color: rgba(255, 255, 255, 0.3);
  margin: 0 0 50px 0;
  text-transform: uppercase;
}

/* 进度圆环 */
.progress-ring {
  width: 220px;
  height: 220px;
  position: relative;
}

.progress-ring svg {
  transform: rotate(-90deg);
}

.progress-ring circle.track {
  fill: none;
  stroke: rgba(255, 255, 255, 0.06);
  stroke-width: 4;
}

.progress-ring circle.progress {
  fill: none;
  stroke: url(#progress-gradient);
  stroke-width: 4;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.5s ease;
}

.progress-ring circle.progress.error {
  stroke: #ff6b6b;
}

.ring-content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.percentage {
  font-size: 48px;
  font-weight: 200;
  color: #fff;
  letter-spacing: 2px;
}

.percentage.error {
  color: #ff6b6b;
  font-size: 56px;
}

.phase-text {
  font-size: 13px;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 8px;
  letter-spacing: 2px;
}

/* 错误区域 */
.error-section {
  margin-top: 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.error-message {
  color: rgba(255, 107, 107, 0.9);
  font-size: 14px;
  max-width: 300px;
  text-align: center;
  margin: 0;
}

.retry-btn {
  padding: 12px 32px;
  background: transparent;
  border: 1px solid rgba(255, 107, 107, 0.4);
  border-radius: 24px;
  color: rgba(255, 107, 107, 0.9);
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s ease;
  letter-spacing: 1px;
}

.retry-btn:hover {
  background: rgba(255, 107, 107, 0.1);
  border-color: rgba(255, 107, 107, 0.6);
}

/* Tips 区域 */
.tips-section {
  margin-top: 50px;
  text-align: center;
}

.tips-label {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.25);
  letter-spacing: 3px;
  text-transform: uppercase;
  margin-bottom: 12px;
}

.tips {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.45);
  max-width: 300px;
  line-height: 1.6;
  transition: opacity 0.3s ease;
}

/* 底部 */
.footer {
  position: absolute;
  bottom: 24px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-between;
  padding: 0 32px;
}

.elapsed, .version {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.2);
  letter-spacing: 1px;
}
</style>
