const HP_BAR_WIDTH = 30;
const HP_BAR_HEIGHT = 4;
const HP_BAR_OFFSET_Y = -30;
const GRID = 80;

export class BaseEnemy {
  constructor(scene, x, y, player, config) {
    this.scene = scene;
    this.player = player;

    this.maxHp = config.hp;
    this.hp = config.hp;
    this.speed = config.speed;
    this.xp = config.xp;
    this.contactDamage = config.contactDamage ?? 10;
    this.radius = config.radius ?? 14;
    this.frameOffset = config.frameOffset ?? 0;

    this._dying = false;
    this._contactTimer = 0;

    this._createAnims();
    this._buildSprite(x, y);
    this._buildHpBar(x, y);
  }

  _createAnims() {
    const anims = this.scene.anims;
    const key = `enemy-walk-${this.frameOffset}`;
    if (!anims.exists(key)) {
      anims.create({
        key,
        frames: anims.generateFrameNumbers('enemies', { frames: [this.frameOffset, this.frameOffset + 1] }),
        frameRate: 6,
        repeat: -1,
      });
    }
  }

  _buildSprite(x, y) {
    this.sprite = this.scene.add.sprite(x, y, 'enemies', this.frameOffset).setDepth(5);
    this.scene.physics.add.existing(this.sprite);
    // Circle hitbox centered in the 48×48 frame
    const offset = 24 - this.radius;
    this.sprite.body.setCircle(this.radius, offset, offset);
    this.sprite.play(`enemy-walk-${this.frameOffset}`);
  }

  _buildHpBar(x, y) {
    this._hpBg   = this.scene.add.rectangle(x, y + HP_BAR_OFFSET_Y, HP_BAR_WIDTH, HP_BAR_HEIGHT, 0x333333);
    this._hpFill = this.scene.add.rectangle(x, y + HP_BAR_OFFSET_Y, HP_BAR_WIDTH, HP_BAR_HEIGHT, 0x00ff44);
  }

  get x() { return this.sprite.x; }
  get y() { return this.sprite.y; }
  /** False while dying so WaveManager stops tracking and wave-clear can fire. */
  get active() { return !this._dying && (this.sprite?.active ?? false); }

  takeDamage(amount) {
    if (this._dying) return;
    this.hp -= amount;
    this._updateHpBar();
    if (this.hp <= 0) this._die();
  }

  _updateHpBar() {
    const ratio = Math.max(0, this.hp / this.maxHp);
    this._hpFill.width = HP_BAR_WIDTH * ratio;
    this._hpFill.x = this.x - (HP_BAR_WIDTH * (1 - ratio)) / 2;
  }

  _syncBarPosition() {
    this._hpBg.setPosition(this.x, this.y + HP_BAR_OFFSET_Y);
    this._hpFill.setPosition(
      this.x - (HP_BAR_WIDTH * (1 - Math.max(0, this.hp / this.maxHp))) / 2,
      this.y + HP_BAR_OFFSET_Y
    );
  }

  _die() {
    this._dying = true;
    if (this._deathSound) this.scene.sound.play(this._deathSound, { volume: 0.5 });
    this.scene.events.emit('enemy-killed', { xp: this.xp, x: this.x, y: this.y });

    // Stop movement and hide HP bar immediately
    this.sprite.body.setVelocity(0, 0);
    this._hpBg.destroy();
    this._hpFill.destroy();
    this._hpBg = null;
    this._hpFill = null;

    // Show death frame
    this.sprite.anims.stop();
    this.sprite.setFrame(this.frameOffset + 2);

    // After 2 seconds, fade out and destroy
    this.scene.time.delayedCall(2000, () => {
      if (!this.sprite?.active) return;
      this.scene.tweens.add({
        targets: this.sprite,
        alpha: 0,
        duration: 400,
        onComplete: () => this.sprite?.destroy(),
      });
    });
  }

  _checkContact(delta) {
    this._contactTimer -= delta;
    if (this._contactTimer > 0) return;

    const dist = Phaser.Math.Distance.Between(this.x, this.y, this.player.x, this.player.y);
    if (dist < this.radius + 16) {
      this.player.takeDamage(this.contactDamage);
      this._contactTimer = 800;
    }
  }

  update(delta) {
    if (this._dying) return;
    this._syncBarPosition();
    this._checkContact(delta);
  }

  _gridDeathPulse() {
    if (!this._deathPulseColor || !this.scene._pulseEffects) return;
    const scene = this.scene;
    const W = scene.scale.width;
    const H = scene.scale.height;
    const col = Math.floor(this.x / GRID);
    const row = Math.floor(this.y / GRID);
    const color = this._deathPulseColor;

    const makeTile = (c, r, alpha) => {
      if (c < 0 || r < 0 || c * GRID >= W || r * GRID >= H) return null;
      return scene.add.rectangle(
        c * GRID + GRID / 2, r * GRID + GRID / 2,
        GRID, GRID, color, alpha,
      ).setDepth(2);
    };

    const center = makeTile(col, row, 0.55);
    const adjacents = [];
    [[-1, 0], [1, 0], [0, -1], [0, 1]].forEach(([dc, dr]) => {
      const t = makeTile(col + dc, row + dr, 0.38);
      if (t) { t.setVisible(false); adjacents.push(t); }
    });

    scene._pulseEffects.push({
      center, adjacents, elapsed: 0, adjSpawned: false,
      ADJ_MS: 80, FADE_MS: 120, END_MS: 400,
    });
  }

  destroy() {
    this.sprite?.destroy();
    this._hpBg?.destroy();
    this._hpFill?.destroy();
  }
}
