export class VialDisplay {
  constructor(scene, x, y, label, fillColor, borderColor) {
    this.scene       = scene;
    this.baseX       = x;
    this.baseY       = y;
    this.label       = label;
    this.fillColor   = fillColor;
    this.borderColor = borderColor;

    this.VIAL_W        = 62;
    this.VIAL_H        = 370;
    this.MAX           = 2000;
    this.currentAmount = 0;
    this._shakeTween   = null;
    this._shakeApplied = 0; // last threshold at which shake was started
    this._won          = false;

    this._build();
  }

  _build() {
    const { scene, baseX, baseY, VIAL_W, VIAL_H, fillColor, borderColor } = this;
    const R = VIAL_W / 2; // radius for rounded top cap

    this.container = scene.add.container(baseX, baseY);

    // Dark glass interior
    const glassBg = scene.add.graphics();
    glassBg.fillStyle(0x060214, 0.95);
    glassBg.fillRoundedRect(-VIAL_W / 2, 0, VIAL_W, VIAL_H, { tl: R, tr: R, bl: 6, br: 6 });
    this.container.add(glassBg);

    // Fill graphic — redrawn dynamically
    this.fillGfx = scene.add.graphics();
    this.container.add(this.fillGfx);

    // Glass border rendered on top of fill so it stays crisp
    const border = scene.add.graphics();
    border.lineStyle(3, borderColor, 0.9);
    border.strokeRoundedRect(-VIAL_W / 2, 0, VIAL_W, VIAL_H, { tl: R, tr: R, bl: 6, br: 6 });
    // Outer glow ring
    border.lineStyle(10, borderColor, 0.18);
    border.strokeRoundedRect(-VIAL_W / 2 - 5, -5, VIAL_W + 10, VIAL_H + 10, { tl: R + 5, tr: R + 5, bl: 10, br: 10 });
    // Left-side glass highlight
    border.lineStyle(2, 0xffffff, 0.22);
    border.beginPath();
    border.moveTo(-VIAL_W / 2 + 6, R + 6);
    border.lineTo(-VIAL_W / 2 + 6, VIAL_H - 12);
    border.strokePath();
    this.container.add(border);

    // Tick marks at $500, $1000, $1500, $2000
    const ticks = scene.add.graphics();
    [500, 1000, 1500, 2000].forEach(amt => {
      const ty = VIAL_H - (amt / this.MAX) * VIAL_H;
      ticks.lineStyle(amt === 2000 ? 2 : 1, borderColor, amt === 2000 ? 0.6 : 0.25);
      ticks.beginPath();
      ticks.moveTo(-VIAL_W / 2 + 4, ty);
      ticks.lineTo( VIAL_W / 2 - 4, ty);
      ticks.strokePath();

      const lbl = scene.add.text(VIAL_W / 2 + 7, ty, `$${amt}`, {
        fontSize: amt === 2000 ? '12px' : '10px',
        fontFamily: 'Georgia, serif',
        color: amt === 2000 ? '#ffd700' : '#4a5a6a',
      }).setOrigin(0, 0.5);
      this.container.add(lbl);
    });
    this.container.add(ticks);

    // Floating amount text shown just above the fill surface
    this.amtText = scene.add.text(0, VIAL_H - 6, '$0', {
      fontSize: '11px',
      fontFamily: 'Georgia, serif',
      fontStyle: 'bold',
      color: '#ffffff',
      stroke: '#000000',
      strokeThickness: 2,
    }).setOrigin(0.5, 1).setAlpha(0);
    this.container.add(this.amtText);

    // Vial label below
    this.container.add(
      scene.add.text(0, VIAL_H + 14, this.label, {
        fontSize: '15px',
        fontFamily: 'Georgia, serif',
        color: '#c8a87e',
        stroke: '#000000',
        strokeThickness: 2,
      }).setOrigin(0.5, 0)
    );

    // Goal text
    this.container.add(
      scene.add.text(0, VIAL_H + 36, 'GOAL: $2,000', {
        fontSize: '10px',
        fontFamily: 'Georgia, serif',
        color: '#3a4a5a',
      }).setOrigin(0.5, 0)
    );
  }

  _drawFill(amount) {
    const { VIAL_W, VIAL_H, MAX, fillColor } = this;
    const capped = Math.min(amount, MAX);
    const fillH  = (capped / MAX) * VIAL_H;

    this.fillGfx.clear();
    if (fillH < 2) {
      this.amtText.setAlpha(0);
      return;
    }

    const fillY = VIAL_H - fillH;
    const R     = VIAL_W / 2;

    // Main fill body
    this.fillGfx.fillStyle(fillColor, 0.88);
    if (fillY < R) {
      // Near the rounded top — match the cap shape
      this.fillGfx.fillRoundedRect(-VIAL_W / 2 + 3, fillY, VIAL_W - 6, fillH, { tl: R - 3, tr: R - 3, bl: 4, br: 4 });
    } else {
      this.fillGfx.fillRoundedRect(-VIAL_W / 2 + 3, fillY, VIAL_W - 6, fillH, 4);
    }

    // Bright liquid surface shimmer
    this.fillGfx.fillStyle(0xffffff, 0.38);
    this.fillGfx.fillRoundedRect(-VIAL_W / 2 + 5, fillY, VIAL_W - 10, 5, 3);

    // Reposition floating amount label just above the surface
    this.amtText.setY(Math.max(fillY - 4, 4));
    this.amtText.setAlpha(1);
    this.amtText.setText(`$${Math.round(capped)}`);
  }

  /**
   * Animate mini coins flying from world position (fromX, fromY) into the vial,
   * then animate the fill rising to targetAmount.
   */
  animateUpdate(targetAmount, fromX, fromY, onComplete) {
    const scene    = this.scene;
    const toAmount = Math.min(targetAmount, this.MAX);

    if (toAmount <= this.currentAmount || this._won) {
      if (onComplete) onComplete();
      return;
    }

    const aimX     = this.baseX;
    const aimY     = this.baseY + this.VIAL_H * 0.78;
    const numCoins = Phaser.Math.Between(5, 8);
    let landed = 0;

    for (let i = 0; i < numCoins; i++) {
      const coin = scene.add.graphics();
      coin.fillStyle(this.fillColor, 1);
      coin.fillCircle(0, 0, 7);
      coin.lineStyle(1.5, 0xffffff, 0.5);
      coin.strokeCircle(0, 0, 7);
      coin.setPosition(fromX + Phaser.Math.Between(-14, 14), fromY);
      coin.setScale(0.1).setAlpha(0);

      scene.tweens.add({
        targets: coin,
        alpha: 1,
        scale: 1,
        duration: 140,
        delay: i * 80,
        ease: 'Back.easeOut',
        onComplete: () => {
          scene.tweens.add({
            targets: coin,
            x: aimX + Phaser.Math.Between(-6, 6),
            y: aimY,
            scale: 0.3,
            alpha: 0.7,
            duration: 480 + i * 50,
            ease: 'Cubic.easeIn',
            onComplete: () => {
              coin.destroy();
              if (++landed === numCoins) this._animateFill(toAmount, onComplete);
            },
          });
        },
      });
    }
  }

  _animateFill(toAmount, onComplete) {
    const scene = this.scene;
    const proxy = { value: this.currentAmount };

    scene.tweens.add({
      targets: proxy,
      value: toAmount,
      duration: 1100,
      ease: 'Cubic.easeOut',
      onUpdate: () => {
        this.currentAmount = proxy.value;
        this._drawFill(proxy.value);
        // Start shaking the first time the fill crosses $1500
        if (proxy.value >= 1500 && this._shakeApplied < 1500) {
          this._shakeApplied = 1500;
          this._applyShake(1500);
        }
      },
      onComplete: () => {
        this.currentAmount = toAmount;
        this._drawFill(toAmount);
        // Update shake to final intensity
        if (toAmount >= 1500) this._applyShake(toAmount);
        if (toAmount >= this.MAX && !this._won) {
          this._won = true;
          this._celebrateWin();
        }
        if (onComplete) onComplete();
      },
    });
  }

  _applyShake(amount) {
    if (amount < 1500) return;

    if (this._shakeTween) {
      this._shakeTween.stop();
      this._shakeTween = null;
      this.container.setX(this.baseX);
    }

    const pct       = Math.min((amount - 1500) / 500, 1);
    const intensity = 3 + pct * 15;         // 3px at $1500 → 18px at $2000
    const speed     = Math.max(22, 100 - pct * 82); // 100ms → 18ms (faster = more frantic)

    this._shakeTween = this.scene.tweens.add({
      targets: this.container,
      x: { from: this.baseX - intensity, to: this.baseX + intensity },
      duration: speed,
      yoyo: true,
      repeat: -1,
      ease: 'Sine.easeInOut',
    });
  }

  _celebrateWin() {
    const scene = this.scene;

    // Stop shaking and snap back to position
    if (this._shakeTween) {
      this._shakeTween.stop();
      this._shakeTween = null;
    }
    this.container.setX(this.baseX);

    // Rapid flash on the fill
    scene.tweens.add({
      targets: this.fillGfx,
      alpha: { from: 1, to: 0.1 },
      duration: 90,
      yoyo: true,
      repeat: 7,
    });

    // Expanding burst ring from vial center
    const burst = scene.add.graphics();
    burst.lineStyle(6, this.borderColor, 1);
    burst.strokeCircle(0, 0, 20);
    burst.setPosition(this.baseX, this.baseY + this.VIAL_H / 2);
    scene.tweens.add({
      targets: burst,
      scaleX: 6, scaleY: 6,
      alpha: 0,
      duration: 700,
      ease: 'Cubic.easeOut',
      onComplete: () => burst.destroy(),
    });

    // Winner badge punches in above the vial
    const badge = scene.add.text(this.baseX, this.baseY - 22, '✦ FULL ✦', {
      fontSize: '16px',
      fontFamily: 'Georgia, serif',
      fontStyle: 'bold',
      color: '#ffd700',
      stroke: '#000000',
      strokeThickness: 3,
      shadow: { offsetX: 0, offsetY: 0, color: '#ffd700', blur: 14, fill: true },
    }).setOrigin(0.5, 0.5).setAlpha(0).setScale(0.3);

    scene.tweens.add({
      targets: badge,
      alpha: 1,
      scale: 1,
      y: this.baseY - 40,
      duration: 500,
      ease: 'Back.easeOut',
    });

    scene.game.events.emit('vial-winner', { winner: this.label });
  }
}
