import {
  BALL_SPLIT_ANGLE,
  CONTAINER_WIDTH,
  PADDLE_WIDE_WIDTH,
  PADDLE_WIDTH,
  PERK_BALL_SPEED_DECREASE,
  PERK_DURATION_SEC,
} from '../../config';
import { clone } from '../../entities/ball/clone/clone';
import { Game } from '../../game';
import { calculateAABBCollision } from '../calculateAABBCollision/calculateAABBCollision';

/**
 * Обновляет состояние бонусов, меняет положение, проверяет столкновение с ракеткой и выход за границу поля
 * @param {Game} game экземпляр класса игры
 * @param {number} containerHeight высота игрового контейнера в пикселях
 * @param {number} deltaTime изменение времени из Ticker
 */
export function updatePerks(game, containerHeight, deltaTime) {
  try {
    if (!(game instanceof Game)) {
      throw new Error('Аргумент game должен быть экземпляром класса игры');
    }

    if (typeof containerHeight !== 'number' || containerHeight <= 0) {
      throw new Error('Высота игрового контейнера должна быть положительным числом');
    }

    if (typeof deltaTime !== 'number' || deltaTime <= 0) {
      throw new Error('Значение изменения времени должно быть положительным числом');
    }

    const { paddle } = game;

    for (const perk of game.perks) {
      perk.moveForward(deltaTime);

      const perkObject = {
        left: perk.x,
        right: perk.x + perk.width,
        top: perk.y,
        bottom: perk.y + perk.height,
      };
      const paddleObject = {
        left: paddle.x,
        right: paddle.x + paddle.width,
        top: paddle.y,
        bottom: paddle.y + paddle.height,
      };

      const isCollided = calculateAABBCollision(perkObject, paddleObject);

      if (isCollided) {
        switch (perk.type) {
          case 'slow':
            for (const ball of game.balls) {
              if (ball.speed - PERK_BALL_SPEED_DECREASE > 0) {
                ball.increaseSpeed(-1 * PERK_BALL_SPEED_DECREASE);
              }
            }
            setTimeout(() => {
              for (const ball of game.balls) {
                ball.increaseSpeed(PERK_BALL_SPEED_DECREASE);
              }
            }, PERK_DURATION_SEC * 1000);
            break;
          case 'wide':
            paddle.width = PADDLE_WIDE_WIDTH;
            paddle.moveTo(paddle.x, 0, CONTAINER_WIDTH);
            setTimeout(() => {
              paddle.width = PADDLE_WIDTH;
            }, PERK_DURATION_SEC * 1000);
            break;
          case 'life':
            game.livesAmount += 1;
            break;
          case 'clone':
            // Основной мяч делится на два клона, разлетающихся под углом
            game.balls.push(clone(game.ball, BALL_SPLIT_ANGLE), clone(game.ball, -BALL_SPLIT_ANGLE));
            break;
          default:
            break;
        }

        perk.alive = false;
      } else if (perk.y > containerHeight) {
        perk.alive = false;
      }
    }

    game.perks = game.perks.filter((perk) => perk.alive);
  } catch (err) {
    console.error(err);
    return null;
  }
}
