/** Tiny particle system — frost dust, star sparkles, damage bursts, rings. */

export interface Particle {
  x: number;
  y: number;
  vx: number;
  vy: number;
  life: number;
  maxLife: number;
  size: number;
  color: string;
  gravity: number;
  glow: boolean;
}

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

  spawn(p: Partial<Particle> & { x: number; y: number }): void {
    const life = p.life ?? 0.6;
    this.list.push({
      vx: 0,
      vy: 0,
      size: 3,
      color: '#d4e2ee',
      gravity: 0,
      glow: false,
      ...p,
      life,
      maxLife: p.maxLife ?? life,
    });
  }

  /** frost puff at the feet — landings / direction changes / wall slides */
  dust(x: number, y: number, count = 6, spread = 60): void {
    for (let i = 0; i < count; i++) {
      this.spawn({
        x: x + (Math.random() - 0.5) * 14,
        y: y - Math.random() * 4,
        vx: (Math.random() - 0.5) * spread,
        vy: -Math.random() * 40 - 10,
        life: 0.3 + Math.random() * 0.25,
        size: 2 + Math.random() * 3,
        color: 'rgba(190,210,230,0.7)',
        gravity: -60, // frost motes drift up and slow
      });
    }
  }

  burst(x: number, y: number, color: string, count = 14): void {
    for (let i = 0; i < count; i++) {
      const a = Math.random() * Math.PI * 2;
      const sp = 60 + Math.random() * 160;
      this.spawn({
        x, y,
        vx: Math.cos(a) * sp,
        vy: Math.sin(a) * sp - 40,
        life: 0.4 + Math.random() * 0.4,
        size: 2 + Math.random() * 3,
        color,
        gravity: 300,
        glow: true,
      });
    }
  }

  sparkle(x: number, y: number, color = '#aee6ff'): void {
    this.spawn({
      x: x + (Math.random() - 0.5) * 30,
      y: y + (Math.random() - 0.5) * 30,
      vx: (Math.random() - 0.5) * 20,
      vy: -20 - Math.random() * 30,
      life: 0.5 + Math.random() * 0.6,
      size: 1.5 + Math.random() * 2,
      color,
      glow: true,
    });
  }

  /** the wall-kick / pickup ring */
  ring(x: number, y: number, color = '#cfeaff'): void {
    for (let i = 0; i < 12; i++) {
      const a = (i / 12) * Math.PI * 2;
      this.spawn({
        x, y,
        vx: Math.cos(a) * 130,
        vy: Math.sin(a) * 45,
        life: 0.32,
        size: 2.5,
        color,
        glow: true,
      });
    }
  }

  update(dt: number): void {
    for (let i = this.list.length - 1; i >= 0; i--) {
      const p = this.list[i];
      p.life -= dt;
      if (p.life <= 0) {
        this.list.splice(i, 1);
        continue;
      }
      p.vy += p.gravity * dt;
      p.x += p.vx * dt;
      p.y += p.vy * dt;
    }
  }

  draw(ctx: CanvasRenderingContext2D): void {
    for (const p of this.list) {
      const t = p.life / p.maxLife;
      ctx.globalAlpha = Math.min(1, t * 1.6);
      if (p.glow) {
        ctx.shadowBlur = 8;
        ctx.shadowColor = p.color;
      }
      ctx.fillStyle = p.color;
      ctx.beginPath();
      ctx.arc(p.x, p.y, p.size * (0.5 + t * 0.5), 0, Math.PI * 2);
      ctx.fill();
      ctx.shadowBlur = 0;
    }
    ctx.globalAlpha = 1;
  }
}
