/**
 * PowerUp.js
 * Power-up item entity with type, position, timer, and blink animation.
 */

const {
  POWERUP_TYPE,
  POWERUP_DURATION,
  TILE_SIZE,
  MAP_OFFSET_X,
  MAP_OFFSET_Y,
  MAP_WIDTH,
  MAP_HEIGHT,
  GRID_COLS,
  GRID_ROWS,
} = require('../base/GameGlobal');

/** Power-up visual config */
const POWERUP_VISUALS = {
  [POWERUP_TYPE.STAR]: { emoji: '⭐', color: '#FFD700', label: 'STAR' },
  [POWERUP_TYPE.CLOCK]: { emoji: '🕒', color: '#87CEEB', label: 'CLOCK' },
  [POWERUP_TYPE.BOMB]: { emoji: '💣', color: '#FF4500', label: 'BOMB' },
  [POWERUP_TYPE.HELMET]: { emoji: '🛡️', color: '#00CED1', label: 'SHIELD' },
  [POWERUP_TYPE.SHOVEL]: { emoji: '🏠', color: '#8B4513', label: 'SHOVEL' },
  [POWERUP_TYPE.TANK]: { emoji: '+1', color: '#32CD32', label: 'LIFE' },
};

class PowerUp {
  /**
   * @param {string} type - POWERUP_TYPE value.
   * @param {number} x - Pixel X.
   * @param {number} y - Pixel Y.
   */
  constructor(type, x, y) {
    this.type = type;
    this.x = x;
    this.y = y;
    this.alive = true;
    this.size = TILE_SIZE * 0.9;
    this.halfSize = this.size / 2;

    this._timer = 0;
    this._duration = POWERUP_DURATION;
    this._blinkStart = POWERUP_DURATION * 0.7; // start blinking at 70% of duration
    this._visible = true;
    this._blinkTimer = 0;
  }

  /**
   * Update power-up timer and blink.
   * @param {number} dt - Delta time in seconds.
   */
  update(dt) {
    if (!this.alive) return;

    this._timer += dt * 1000;

    // Blink when about to expire
    if (this._timer >= this._blinkStart) {
      this._blinkTimer += dt * 1000;
      if (this._blinkTimer >= 150) {
        this._blinkTimer = 0;
        this._visible = !this._visible;
      }
    }

    // Expire
    if (this._timer >= this._duration) {
      this.alive = false;
    }
  }

  /**
   * Render the power-up.
   * @param {CanvasRenderingContext2D} ctx
   */
  render(ctx) {
    if (!this.alive || !this._visible) return;

    const visual = POWERUP_VISUALS[this.type];
    const x = this.x - this.halfSize;
    const y = this.y - this.halfSize;

    // Background glow
    ctx.save();
    ctx.globalAlpha = 0.3;
    ctx.fillStyle = visual.color;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.halfSize + 4, 0, Math.PI * 2);
    ctx.fill();
    ctx.restore();

    // Background box
    ctx.fillStyle = '#000000';
    ctx.globalAlpha = 0.7;
    ctx.fillRect(x, y, this.size, this.size);
    ctx.globalAlpha = 1;

    // Border
    ctx.strokeStyle = visual.color;
    ctx.lineWidth = 2;
    ctx.strokeRect(x, y, this.size, this.size);

    // Icon/text
    ctx.fillStyle = visual.color;
    ctx.font = `bold ${Math.floor(this.size * 0.5)}px Arial`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';

    if (this.type === POWERUP_TYPE.TANK) {
      ctx.fillText('+1', this.x, this.y);
    } else {
      ctx.font = `${Math.floor(this.size * 0.6)}px Arial`;
      ctx.fillText(visual.emoji, this.x, this.y);
    }
  }

  /**
   * Get bounding box for collision.
   * @returns {{x: number, y: number, w: number, h: number}}
   */
  getBounds() {
    return {
      x: this.x - this.halfSize,
      y: this.y - this.halfSize,
      w: this.size,
      h: this.size,
    };
  }

  /**
   * Generate a random position on the map (avoiding terrain).
   * @param {MapManager} mapManager
   * @returns {{x: number, y: number}}
   */
  static randomPosition(mapManager) {
    let attempts = 0;
    while (attempts < 50) {
      const col = Math.floor(Math.random() * GRID_COLS);
      const row = Math.floor(Math.random() * (GRID_ROWS - 2)) + 1; // avoid top/bottom rows
      const terrain = mapManager.getTerrain(row, col);

      // Only place on empty tiles
      if (terrain === 0) { // TERRAIN.EMPTY
        return {
          x: MAP_OFFSET_X + col * TILE_SIZE + TILE_SIZE / 2,
          y: MAP_OFFSET_Y + row * TILE_SIZE + TILE_SIZE / 2,
        };
      }
      attempts++;
    }

    // Fallback: center of map
    return {
      x: MAP_OFFSET_X + MAP_WIDTH / 2,
      y: MAP_OFFSET_Y + MAP_HEIGHT / 2,
    };
  }

  /**
   * Get a random power-up type based on level-adjusted probabilities.
   * @param {number} levelNum - Current level number.
   * @returns {string} POWERUP_TYPE value.
   */
  static randomType(levelNum) {
    // Base probabilities (weights)
    const weights = {
      [POWERUP_TYPE.STAR]: Math.max(10, 30 - levelNum), // decreases with level
      [POWERUP_TYPE.CLOCK]: 15,
      [POWERUP_TYPE.BOMB]: 10,
      [POWERUP_TYPE.HELMET]: 15,
      [POWERUP_TYPE.SHOVEL]: 10,
      [POWERUP_TYPE.TANK]: 10,
    };

    const totalWeight = Object.values(weights).reduce((a, b) => a + b, 0);
    let rand = Math.random() * totalWeight;

    for (const [type, weight] of Object.entries(weights)) {
      rand -= weight;
      if (rand <= 0) return type;
    }

    return POWERUP_TYPE.STAR; // fallback
  }
}

module.exports = PowerUp;
