<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import gsap from 'gsap'
import { useAppStore } from '~/stores/app'
import { usePageScrollLock } from '~/composables/usePageScrollLock'

const loaderRef = ref<HTMLElement | null>(null)
const loaderBarRef = ref<HTMLElement | null>(null)
const appStore = useAppStore()

// 加载期间锁定页面滚动（注意：Pinia 的 state 是自动解包的，必须用 computed 包装才能保持响应式）
usePageScrollLock(computed(() => appStore.isAppLoading))

let loaderTween: gsap.core.Tween | null = null
let removeLoadListener: (() => void) | null = null
let introStartTimer: ReturnType<typeof window.setTimeout> | null = null

onMounted(() => {
  if (!loaderRef.value || !loaderBarRef.value) return

  // 1. 初始化 GSAP 样式状态
  gsap.set(loaderRef.value, { display: 'grid', yPercent: 0, autoAlpha: 1 })
  gsap.set(loaderBarRef.value, { scaleX: 0.18, transformOrigin: 'left center' })

  // 2. 进度条往复加载动画
  loaderTween = gsap.to(loaderBarRef.value, {
    scaleX: 0.82,
    duration: 1.2,
    ease: 'power1.inOut',
    repeat: -1,
    yoyo: true,
  })

  const loaderStartedAt = window.performance.now()
  const minLoaderDuration = 1200 // 保证加载动画至少播放 1.2 秒，避免一闪而过

  const finishLoading = () => {
    removeLoadListener?.()
    if (introStartTimer) clearTimeout(introStartTimer)

    // 计算还需要等待多久才能达到最小加载时间
    const remainingTime = Math.max(0, minLoaderDuration - (window.performance.now() - loaderStartedAt))

    introStartTimer = setTimeout(() => {
      // 停止往复动画
      loaderTween?.kill()
      
      // 3. 执行加载器退场动画
      gsap.timeline({
        onComplete: () => {
          gsap.set(loaderRef.value, { display: 'none' })
          appStore.setAppLoading(false) // 触发全局状态，通知其他组件入场
        }
      })
      .to(loaderBarRef.value, { scaleX: 1, duration: 0.25, ease: 'power2.out' })
      .to(loaderRef.value, { yPercent: -100, duration: 0.75, ease: 'power4.inOut' })
    }, remainingTime)
  }

  // 监听浏览器 window.onload 事件以判断页面资源是否加载完毕
  if (document.readyState === 'complete') {
    finishLoading()
  } else {
    window.addEventListener('load', finishLoading, { once: true })
    removeLoadListener = () => window.removeEventListener('load', finishLoading)
  }
})

onBeforeUnmount(() => {
  loaderTween?.kill()
  if (introStartTimer) clearTimeout(introStartTimer)
  removeLoadListener?.()
})
</script>

<template>
  <div ref="loaderRef" class="fixed inset-0 z-[90] grid place-items-center bg-black text-white will-change-transform" aria-hidden="true">
    <div class="w-[min(220px,calc(100vw-48px))] text-xs uppercase tracking-[0.18em]">
      <p class="m-0 mb-[14px]">Loading</p>
      <span class="block h-px w-full overflow-hidden bg-white/20">
        <span ref="loaderBarRef" class="block h-full w-full origin-left scale-x-0 bg-white"></span>
      </span>
    </div>
  </div>
</template>
