// PWA 客户端：注册 Service Worker，并在首次预缓存（或版本更新）时
// 显示一个全屏 modal 进度条，反映离线资源的真实下载进度。

type SWMessage =
  | { type: 'precache-start'; total: number }
  | { type: 'precache-progress'; loaded: number; total: number }
  | { type: 'precache-done'; total: number }

let overlay: HTMLDivElement | null = null
let barFill: HTMLDivElement | null = null
let label: HTMLDivElement | null = null

function injectStyle(): void {
  if (document.getElementById('pwa-precache-style')) return
  const style = document.createElement('style')
  style.id = 'pwa-precache-style'
  style.textContent = `
.pwa-precache {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 22px; padding: 32px;
  background: var(--bg, #1a1a2e);
  color: var(--fg, rgba(255,255,255,0.92));
  font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif;
  transition: opacity .4s ease;
}
.pwa-precache.hide { opacity: 0; pointer-events: none; }
.pwa-precache__icon { width: 96px; height: 96px; border-radius: 22px; box-shadow: 0 8px 30px rgba(0,0,0,.4); }
.pwa-precache__title { font-size: 17px; font-weight: 600; }
.pwa-precache__sub { font-size: 13px; color: var(--fg-dim, rgba(255,255,255,0.6)); margin-top: -10px; }
.pwa-precache__track {
  width: min(78vw, 320px); height: 8px; border-radius: 999px;
  background: var(--bg-soft, rgba(255,255,255,0.06));
  overflow: hidden;
}
.pwa-precache__fill {
  height: 100%; width: 0%;
  background: linear-gradient(90deg, var(--accent, #7c3aed), var(--accent-2, #06b6d4));
  border-radius: 999px; transition: width .25s ease;
}
.pwa-precache__pct { font-size: 13px; color: var(--fg-dim, rgba(255,255,255,0.6)); }
`
  document.head.appendChild(style)
}

function show(): void {
  if (overlay) return
  injectStyle()
  overlay = document.createElement('div')
  overlay.className = 'pwa-precache'
  overlay.innerHTML = `
    <img class="pwa-precache__icon" src="/pwa-192x192.png" alt="" />
    <div class="pwa-precache__title">正在缓存离线资源…</div>
    <div class="pwa-precache__sub">完成后断网也能发牌</div>
    <div class="pwa-precache__track"><div class="pwa-precache__fill"></div></div>
    <div class="pwa-precache__pct">0%</div>
  `
  document.body.appendChild(overlay)
  barFill = overlay.querySelector('.pwa-precache__fill')
  label = overlay.querySelector('.pwa-precache__pct')
}

function update(loaded: number, total: number): void {
  if (!overlay) show()
  const pct = total > 0 ? Math.round((loaded / total) * 100) : 0
  if (barFill) barFill.style.width = `${pct}%`
  if (label) label.textContent = `${pct}%  ·  ${loaded}/${total}`
}

function done(): void {
  if (!overlay) return
  if (barFill) barFill.style.width = '100%'
  overlay.classList.add('hide')
  const el = overlay
  overlay = null
  barFill = null
  label = null
  setTimeout(() => el.remove(), 450)
}

export function setupPWA(): void {
  if (!('serviceWorker' in navigator)) return

  navigator.serviceWorker.addEventListener('message', (event) => {
    const msg = event.data as SWMessage
    if (!msg || typeof msg !== 'object') return
    if (msg.type === 'precache-start') show()
    else if (msg.type === 'precache-progress') update(msg.loaded, msg.total)
    else if (msg.type === 'precache-done') done()
  })

  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js', { scope: '/' }).catch((err) => {
      console.error('[pwa] SW 注册失败', err)
    })
  })
}
