/**
 * DC 空闲庆祝特效模块
 * 当有空闲 DC 充电桩时，触发粒子金雨 + 卡牌弹性入场 + 宝藏光效
 * 优化版：半分辨率 Canvas、30fps、无 save/restore
 */

// ===== 粒子系统 =====
let particleCanvas = null;
let particleCtx = null;
let particles = [];
let particleAnimId = null;
let sourceCards = [];
let onScroll = null;
let resizeHandler = null;
let lastFrameTime = 0;

// Canvas 在视口中的位置

const CANVAS_SCALE = 0.5;
const CANVAS_PAD_TOP = 180;    // 上方留空让粒子上升
const CANVAS_PAD_SIDE = 40;
const CANVAS_PAD_BOTTOM = 60;
const PARTICLE_COLORS = [
  '#fbbf24', '#f59e0b', '#4ade80', '#22d3ee', '#fcd34d',
];

/**
 * 根据所有 DC 卡牌视口位置，计算 Canvas 应该覆盖的区域
 */
function calcCardBounds() {
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
  sourceCards.forEach((card) => {
    const r = card.getBoundingClientRect();
    if (r.width === 0) return;
    if (r.left < minX) minX = r.left;
    if (r.top < minY) minY = r.top;
    if (r.right > maxX) maxX = r.right;
    if (r.bottom > maxY) maxY = r.bottom;
  });
  return { minX, minY, maxX, maxY };
}

function ensureParticleCanvas() {
  if (particleCanvas) return;
  particleCanvas = document.createElement('canvas');
  particleCanvas.id = 'dc-celebration-canvas';
  particleCanvas.style.cssText = `
    position: fixed; pointer-events: none; z-index: 100;
  `;
  document.body.appendChild(particleCanvas);
  particleCtx = particleCanvas.getContext('2d', { alpha: true });

  resizeHandler = () => updateCanvasSize();
  window.addEventListener('resize', resizeHandler);

  onScroll = () => {
    if (onScroll._pending) return;
    onScroll._pending = true;
    requestAnimationFrame(() => {
      onScroll._pending = false;
      updateCanvasSize();
    });
  };
  window.addEventListener('scroll', onScroll, { passive: true });

  updateCanvasSize();
}

function updateCanvasSize() {
  if (!particleCanvas || sourceCards.length === 0) return;

  const b = calcCardBounds();
  const w = Math.max(200, b.maxX - b.minX + CANVAS_PAD_SIDE * 2);
  const h = Math.max(200, b.maxY - b.minY + CANVAS_PAD_TOP + CANVAS_PAD_BOTTOM);
  const left = b.minX - CANVAS_PAD_SIDE;
  const top = b.minY - CANVAS_PAD_TOP;

  particleCanvas.style.left = left + 'px';
  particleCanvas.style.top = top + 'px';
  particleCanvas.style.width = w + 'px';
  particleCanvas.style.height = h + 'px';
  particleCanvas.width = w * CANVAS_SCALE;
  particleCanvas.height = h * CANVAS_SCALE;

  // 更新卡牌在 Canvas 坐标系中的发射位置
  sourceCards.forEach((card) => {
    const r = card.getBoundingClientRect();
    card._vx = (r.left + r.width / 2 - left) * CANVAS_SCALE;
    card._vy = (r.top + r.height * 0.3 - top) * CANVAS_SCALE;
    card._vw = r.width * CANVAS_SCALE;
    card._vh = r.height * CANVAS_SCALE;
  });
}

function spawnParticle(card, intense) {
  const cx = card._vx ?? 0, cy = card._vy ?? 0;
  const cw = card._vw ?? 50, ch = card._vh ?? 60;
  const vx = (Math.random() - 0.5) * (intense ? 100 : 50);
  const vy = -(intense ? 80 + Math.random() * 200 : 40 + Math.random() * 80);
  return {
    x: cx + (Math.random() - 0.5) * cw * 0.6,
    y: cy + (Math.random() - 0.5) * ch * 0.4,
    vx, vy,
    size: intense ? 1 + Math.random() * 3 : 0.6 + Math.random() * 1.8,
    life: 0.6 + Math.random() * 1.2,
    maxLife: 0.6 + Math.random() * 1.2,
    color: PARTICLE_COLORS[Math.floor(Math.random() * PARTICLE_COLORS.length)],
    gravity: 0.2 + Math.random() * 0.4,
    shimmer: Math.random() > 0.8,
  };
}

function burstParticles(count) {
  sourceCards.forEach((card) => {
    for (let i = 0; i < count; i++) particles.push(spawnParticle(card, true));
  });
}

function emitGentle(card, count) {
  for (let i = 0; i < count; i++) particles.push(spawnParticle(card, false));
}

function animateParticles(now) {
  if (!particleCtx) return;

  // 30fps 节流
  if (now - lastFrameTime < 33) {
    particleAnimId = requestAnimationFrame(animateParticles);
    return;
  }
  lastFrameTime = now;

  const ctx = particleCtx;
  ctx.clearRect(0, 0, particleCanvas.width, particleCanvas.height);

  // 就地过滤 + 更新，避免创建新数组
  let writeIdx = 0;
  for (let i = 0; i < particles.length; i++) {
    const p = particles[i];
    p.x += p.vx * 0.033;
    p.y += p.vy * 0.033;
    p.vy += p.gravity;
    p.vx *= 0.993;
    p.life -= 0.033;
    if (p.life <= 0) continue;
    particles[writeIdx++] = p;

    const alpha = p.life / p.maxLife;
    const size = p.size * alpha;
    ctx.globalAlpha = alpha;
    ctx.fillStyle = p.color;

    if (p.shimmer) {
      ctx.shadowColor = p.color;
      ctx.shadowBlur = size * 1.5;
      ctx.beginPath();
      ctx.arc(p.x, p.y, size, 0, Math.PI * 2);
      ctx.fill();
      // 十字光芒
      ctx.shadowBlur = 0;
      ctx.strokeStyle = p.color;
      ctx.lineWidth = 0.3;
      ctx.globalAlpha = alpha * 0.3;
      ctx.beginPath();
      ctx.moveTo(p.x - size * 2, p.y);
      ctx.lineTo(p.x + size * 2, p.y);
      ctx.moveTo(p.x, p.y - size * 2);
      ctx.lineTo(p.x, p.y + size * 2);
      ctx.stroke();
    } else {
      ctx.shadowColor = p.color;
      ctx.shadowBlur = size;
      ctx.beginPath();
      ctx.arc(p.x, p.y, size, 0, Math.PI * 2);
      ctx.fill();
    }
  }
  particles.length = writeIdx;

  // 温和发射（降频）
  if (Math.random() < 0.15) {
    sourceCards.forEach((card) => emitGentle(card, 1));
  }

  particleAnimId = requestAnimationFrame(animateParticles);
}

function stopParticles() {
  if (particleAnimId) { cancelAnimationFrame(particleAnimId); particleAnimId = null; }
  if (onScroll) { window.removeEventListener('scroll', onScroll); onScroll = null; }
  if (resizeHandler) { window.removeEventListener('resize', resizeHandler); resizeHandler = null; }
  particles.length = 0;
  if (particleCanvas && particleCanvas.parentNode) particleCanvas.parentNode.removeChild(particleCanvas);
  particleCanvas = null;
  particleCtx = null;
  sourceCards = [];
}

// ===== 卡牌入场 (GSAP) =====

function animateFreeDCCards() {
  const freeCards = document.querySelectorAll('.card-free.card-dc');
  if (freeCards.length === 0) return Promise.resolve();
  const gsapInstance = globalThis.gsap;
  if (!gsapInstance) return Promise.resolve();

  gsapInstance.set(freeCards, { scale: 0.5, opacity: 0, y: 60, rotationX: 15 });

  return gsapInstance.to(freeCards, {
    scale: 1, opacity: 1, y: 0, rotationX: 0,
    duration: 0.8, ease: 'elastic.out(1, 0.5)',
    stagger: { each: 0.12, from: 'random' },
    onComplete: () => {
      gsapInstance.to(freeCards, {
        scale: 1.03, duration: 0.3, ease: 'power2.out',
        yoyo: true, repeat: 1, stagger: 0.06,
      });
    },
  });
}

function goldenRipple() {
  const dcSection = document.querySelector('#dc-grid');
  if (!dcSection) return;
  const gsapInstance = globalThis.gsap;
  if (!gsapInstance) return;
  const ripple = document.createElement('div');
  ripple.style.cssText = `
    position: absolute; top: 50%; left: 50%; width: 0; height: 0;
    border-radius: 50%; pointer-events: none; z-index: 5;
    background: radial-gradient(circle, rgba(251,191,36,0.3) 0%, rgba(245,158,11,0.1) 40%, transparent 70%);
  `;
  dcSection.style.position = 'relative';
  dcSection.style.overflow = 'visible';
  dcSection.appendChild(ripple);
  gsapInstance.to(ripple, {
    width: '200%', height: '200%', x: '-50%', y: '-50%', opacity: 0,
    duration: 1.2, ease: 'power3.out', onComplete: () => ripple.remove(),
  });
}

// ===== 主入口 =====

let isCelebrating = false;

export async function celebrate(freeDCCount) {
  if (isCelebrating || freeDCCount <= 0) return;
  isCelebrating = true;

  sourceCards = Array.from(document.querySelectorAll('.card-free.card-dc'));
  if (sourceCards.length === 0) { isCelebrating = false; return; }

  ensureParticleCanvas(); // 内部调 updateCanvasSize 初始化坐标

  lastFrameTime = performance.now();
  particleAnimId = requestAnimationFrame(animateParticles);

  burstParticles(20);   // 每卡 20 个（原 50）
  goldenRipple();

  await new Promise((r) => requestAnimationFrame(r));
  await animateFreeDCCards();

  setTimeout(() => burstParticles(10), 600);  // 二次 10 个（原 25）

  setTimeout(() => { stopParticles(); isCelebrating = false; }, 6000); // 6s 停止（原 8s）
}

export function cleanup() {
  stopParticles();
  isCelebrating = false;
}
