import { PERK_DROP_CHANCE, PERK_HEIGHT, PERK_WIDTH } from '../../config';
import { Ball } from '../../entities/ball/ball';
import { Game } from '../../game';
import { calculateAABBCollision } from '../calculateAABBCollision/calculateAABBCollision';
import { calculateDirection } from '../calculateDirection/calculateDirection';
import { spawnRandomPerk } from '../spawnRandomPerk/spawnRandomPerk';

/**
 * Базовое взаимодействие мяча и кирпичей: меняет направление, разрушает кирпич и роняет бонус
 * @param {Game} game экземпляр класса игры
 * @param {Ball} ball мяч
 * @returns {boolean | null} true, если произошло столкновение с кирпичом
 */
export function processBrickCollision(game, ball) {
  try {
    if (!(game instanceof Game)) {
      throw new Error('Аргумент game должен быть экземпляром класса игра');
    }

    if (!(ball instanceof Ball)) {
      throw new Error('Аргумент ball должен быть экземпляром класса мяч');
    }

    for (const brick of game.bricks) {
      if (!brick.alive) {
        continue;
      }

      const ballObject = {
        left: ball.x - ball.radius,
        right: ball.x + ball.radius,
        top: ball.y - ball.radius,
        bottom: ball.y + ball.radius,
      };
      const brickObject = {
        left: brick.x,
        right: brick.x + brick.width,
        top: brick.y,
        bottom: brick.y + brick.height,
      };

      const isCollided = calculateAABBCollision(ballObject, brickObject);

      if (!isCollided) {
        continue;
      }

      const directions = calculateDirection(ballObject, brickObject);

      if (directions === null) {
        continue;
      }

      ball.horizontalSpeed *= directions[0];
      ball.verticalSpeed *= directions[1];
      brick.kill();

      if (!brick.alive && Math.random() < PERK_DROP_CHANCE) {
        const perk = spawnRandomPerk(
          brick.x + brick.width / 2 - PERK_WIDTH / 2,
          brick.y + brick.height / 2 - PERK_HEIGHT / 2,
        );
        game.perks.push(perk);
      }

      return true;
    }

    return false;
  } catch (err) {
    console.error(err);
    return null;
  }
}
