import { GAME_WIDTH, GAME_HEIGHT } from '../config/game.config.js';
import { storage, KEYS } from '../utils/storage.js';

/**
 * Owns a fixed set of pooled Phaser particle emitters, created once per scene.
 * All hot-path particle effects (jump, explosion, boost flame/wind, etc.) reuse
 * these emitters instead of allocating GameObjects + tweens every frame.
 */
export class ParticleManager {
  constructor(scene) {
    this.scene = scene;
    this.quality = ParticleManager.resolveQuality(scene);
    this.low = this.quality === 'low';
    this.emitters = {};
    this._build();
  }

  static resolveQuality(scene) {
    const saved = storage.getItem(KEYS.particleQuality, null);
    if (saved === 'low' || saved === 'high') return saved;
    const d = scene.sys.game.device;
    const small = Math.min(window.innerWidth, window.innerHeight) < 500;
    return (d.os.android || d.os.iOS || small) ? 'low' : 'high';
  }

  _q(high, low) {
    return this.low ? low : high;
  }

  _build() {
    const add = (key, texture, config, depth) => {
      const e = this.scene.add.particles(0, 0, texture, { emitting: false, ...config });
      e.setDepth(depth);
      this.emitters[key] = e;
      return e;
    };

    // --- Burst emitters (manual explode) ---
    add('jump', 'px_square', {
      lifespan: 260,
      speed: { min: 40, max: 130 },
      angle: { min: 250, max: 290 },
      scale: { start: 0.9, end: 0 },
      alpha: { start: 0.9, end: 0 },
      rotate: { min: -180, max: 180 },
      tint: [0xa855f7, 0xc084fc, 0x8b5cf6],
      frequency: -1,
    }, -2);

    add('explosion', 'px_square', {
      lifespan: 500,
      speed: { min: 60, max: 170 },
      angle: { min: 0, max: 360 },
      scale: { start: 1.1, end: 0 },
      alpha: { start: 1, end: 0 },
      rotate: { min: -180, max: 180 },
      tint: [0xef4444, 0xf97316, 0xfca5a5],
      frequency: -1,
    }, 1);

    add('powerup', 'px_square', {
      lifespan: 600,
      speed: { min: 50, max: 150 },
      angle: { min: 0, max: 360 },
      scale: { start: 1, end: 0 },
      alpha: { start: 1, end: 0 },
      tint: [0xffd700, 0xa855f7, 0x22c55e],
      frequency: -1,
    }, 1);

    add('puff', 'px_soft', {
      lifespan: { min: 500, max: 800 },
      speed: { min: 30, max: 70 },
      angle: { min: 0, max: 360 },
      scale: { start: 1.2, end: 2.2 },
      alpha: { start: 0.55, end: 0 },
      tint: [0x888888, 0xaaaaaa, 0x666666],
      frequency: -1,
    }, -2);

    add('sparks', 'px_square', {
      lifespan: 500,
      speed: { min: 70, max: 150 },
      angle: { min: 0, max: 360 },
      scale: { start: 1, end: 0 },
      alpha: { start: 1, end: 0 },
      frequency: -1,
    }, 1);

    // --- Flow emitters (toggle start/stop, follow a position) ---
    add('flame', 'px_soft', {
      lifespan: { min: 360, max: 620 },
      speedY: { min: 120, max: 260 },
      speedX: { min: -45, max: 45 },
      scale: { start: this._q(1.2, 0.9), end: 0 },
      alpha: { start: 0.95, end: 0 },
      tint: [0xffd700, 0xffaa00, 0xff6600, 0xff3300, 0xaa0000],
      blendMode: 'ADD',
      frequency: this._q(28, 55),
      quantity: 1,
    }, -2);

    add('wind', 'px_streak', {
      lifespan: { min: 300, max: 540 },
      speedY: { min: 30, max: 80 },
      speedX: { min: -25, max: 25 },
      scale: { start: 1, end: 0.3 },
      alpha: { start: 0.7, end: 0 },
      tint: [0xffffff, 0xbbddff, 0x66aaff, 0x4477cc],
      blendMode: 'ADD',
      frequency: this._q(40, 80),
      quantity: 1,
    }, -2);

    add('spring', 'px_square', {
      lifespan: { min: 400, max: 620 },
      speedY: { min: 60, max: 130 },
      speedX: { min: -35, max: 35 },
      scale: { start: 1, end: 0 },
      alpha: { start: 0.9, end: 0 },
      rotate: { min: -180, max: 180 },
      tint: [0xffd700, 0xfff066, 0x22c55e, 0xa3e635],
      frequency: this._q(35, 70),
      quantity: 1,
    }, -2);

    add('speedline', 'px_streak', {
      lifespan: { min: 280, max: 450 },
      speedY: { min: 150, max: 300 },
      scaleX: { start: 1, end: 1 },
      scaleY: { start: 3.5, end: 1.5 },
      alpha: { start: 0.45, end: 0 },
      tint: 0xffffff,
      frequency: -1,
    }, -1);
  }

  // --- Bursts ---
  burstJump(x, y) {
    this.emitters.jump.explode(this._q(8, 4), x, y);
  }

  burstExplosion(x, y) {
    this.emitters.explosion.explode(this._q(14, 7), x, y);
  }

  burstPowerup(x, y) {
    this.emitters.powerup.explode(this._q(12, 6), x, y);
  }

  puff(x, y) {
    this.emitters.puff.explode(this._q(8, 4), x, y);
  }

  // --- Boost flow control (called each frame while active) ---
  flameAt(x, y) {
    const e = this.emitters.flame;
    e.setPosition(x, y);
    if (!e.emitting) e.start();
  }

  windAt(x, y) {
    const e = this.emitters.wind;
    e.setPosition(x, y);
    if (!e.emitting) e.start();
  }

  springAt(x, y) {
    const e = this.emitters.spring;
    e.setPosition(x, y);
    if (!e.emitting) e.start();
  }

  stopFlow() {
    if (this.emitters.flame.emitting) this.emitters.flame.stop();
    if (this.emitters.wind.emitting) this.emitters.wind.stop();
    if (this.emitters.spring.emitting) this.emitters.spring.stop();
  }

  speedLine() {
    if (this.low) return;
    const cam = this.scene.cameras.main;
    const left = Math.random() < 0.5;
    const x = left ? Phaser.Math.Between(0, 40) : Phaser.Math.Between(GAME_WIDTH - 40, GAME_WIDTH);
    const y = cam.scrollY + Phaser.Math.Between(0, GAME_HEIGHT);
    this.emitters.speedline.emitParticleAt(x, y, 1);
  }

  // --- Boost start burst: rings (rare, 2 sprites) + spark explode ---
  boostBurst(x, y, type) {
    let ringColor, sparkColor;
    if (type === 'rocket') { ringColor = 0xff6600; sparkColor = 0xffd700; }
    else if (type === 'spring') { ringColor = 0x22c55e; sparkColor = 0xffd700; }
    else { ringColor = 0x88ccff; sparkColor = 0xffffff; }

    this._ring(x, y, ringColor, 0.6, 380);
    this._ring(x, y, sparkColor, 0.45, 520);

    this.emitters.sparks.setParticleTint(sparkColor);
    this.emitters.sparks.explode(this._q(type === 'rocket' ? 16 : 10, 6), x, y);

    const shake = type === 'rocket' ? 0.006 : type === 'spring' ? 0.002 : 0.003;
    const dur = type === 'rocket' ? 120 : type === 'spring' ? 60 : 80;
    this.scene.cameras.main.shake(dur, shake);
  }

  _ring(x, y, color, alpha, duration) {
    const ring = this.scene.add.image(x, y, 'px_ring').setTint(color).setAlpha(alpha).setDepth(-1).setScale(0.4);
    this.scene.tweens.add({
      targets: ring,
      scale: 3,
      alpha: 0,
      duration,
      ease: 'Quad.easeOut',
      onComplete: () => ring.destroy(),
    });
  }

  destroy() {
    Object.values(this.emitters).forEach((e) => {
      if (e && e.destroy) e.destroy();
    });
    this.emitters = {};
  }
}
