interface Particle {
  kind: 'coin' | 'steam' | 'spark' | 'text' | 'emoji';
  x: number;
  y: number;
  vx: number;
  vy: number;
  life: number;
  maxLife: number;
  size: number;
  text?: string;
  color?: string;
}

export class Particles {
  list: Particle[] = [];

  coinBurst(x: number, y: number, n = 7): void {
    for (let i = 0; i < n; i++) {
      const a = Math.random() * Math.PI * 2;
      const sp = 60 + Math.random() * 120;
      this.list.push({
        kind: 'coin',
        x,
        y,
        vx: Math.cos(a) * sp,
        vy: Math.sin(a) * sp - 130,
        life: 0,
        maxLife: 0.8 + Math.random() * 0.3,
        size: 4 + Math.random() * 4,
      });
    }
  }

  text(x: number, y: number, text: string, color = '#ffd763'): void {
    this.list.push({ kind: 'text', x, y, vx: 0, vy: -52, life: 0, maxLife: 1.1, size: 21, text, color });
  }

  emoji(x: number, y: number, glyph: string, size = 30): void {
    this.list.push({ kind: 'emoji', x, y, vx: 0, vy: -38, life: 0, maxLife: 1.2, size, text: glyph });
  }

  steam(x: number, y: number): void {
    this.list.push({
      kind: 'steam',
      x: x + (Math.random() - 0.5) * 14,
      y,
      vx: (Math.random() - 0.5) * 8,
      vy: -22 - Math.random() * 16,
      life: 0,
      maxLife: 1.6 + Math.random() * 0.8,
      size: 5 + Math.random() * 5,
    });
  }

  spark(x: number, y: number): void {
    this.list.push({
      kind: 'spark',
      x,
      y,
      vx: (Math.random() - 0.5) * 90,
      vy: -50 - Math.random() * 80,
      life: 0,
      maxLife: 0.35 + Math.random() * 0.25,
      size: 2 + Math.random() * 2,
    });
  }

  update(dt: number): void {
    for (const p of this.list) {
      p.life += dt;
      p.x += p.vx * dt;
      p.y += p.vy * dt;
      if (p.kind === 'coin') p.vy += 420 * dt;
      if (p.kind === 'steam') {
        p.size += 9 * dt;
        p.vx += Math.sin(p.life * 5) * 14 * dt;
      }
      if (p.kind === 'spark') p.vy += 320 * dt;
    }
    this.list = this.list.filter((p) => p.life < p.maxLife);
  }

  draw(ctx: CanvasRenderingContext2D): void {
    for (const p of this.list) {
      const k = 1 - p.life / p.maxLife;
      ctx.globalAlpha = Math.min(1, k * 1.6);
      switch (p.kind) {
        case 'coin': {
          ctx.fillStyle = '#ffd24a';
          ctx.strokeStyle = '#a8720d';
          ctx.lineWidth = 1.5;
          ctx.beginPath();
          ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
          ctx.fill();
          ctx.stroke();
          break;
        }
        case 'steam': {
          ctx.fillStyle = 'rgba(255,250,242,0.55)';
          ctx.beginPath();
          ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
          ctx.fill();
          break;
        }
        case 'spark': {
          ctx.fillStyle = p.life % 0.1 < 0.05 ? '#ffd24a' : '#ff8a3d';
          ctx.fillRect(p.x - p.size / 2, p.y - p.size / 2, p.size, p.size);
          break;
        }
        case 'text': {
          ctx.font = `900 ${p.size}px ui-rounded, system-ui, sans-serif`;
          ctx.textAlign = 'center';
          ctx.lineWidth = 4;
          ctx.strokeStyle = '#3a2418';
          ctx.strokeText(p.text!, p.x, p.y);
          ctx.fillStyle = p.color!;
          ctx.fillText(p.text!, p.x, p.y);
          break;
        }
        case 'emoji': {
          ctx.font = `${p.size}px system-ui, sans-serif`;
          ctx.textAlign = 'center';
          ctx.fillText(p.text!, p.x, p.y);
          break;
        }
      }
    }
    ctx.globalAlpha = 1;
  }
}
