import { CONTAINER_HEIGHT, CONTAINER_WIDTH } from '../../config';
import { Game } from '../../game';
import { tick } from './tick';

describe('tick', () => {
  it('Возвращает корректное значние при неверных типах аргументов', () => {
    expect(tick(null, 1, 1, 1)).toBeNull();
    expect(tick(1, null, 1, 1)).toBeNull();
    expect(tick(1, 1, null, 1)).toBeNull();
    expect(tick(1, 1, 1, null)).toBeNull();
  });

  it('Возвращает корректное значние и не изменяет свойства game при неверых размерах контейнера', () => {
    const levels = [[[1]]];
    const game = new Game(levels);
    const ballX = game.ball.x;
    const ballY = game.ball.y;
    expect(tick(game, -1, -1, 1)).toBeNull();
    expect(game.ball.x).toBe(ballX);
    expect(game.ball.y).toBe(ballY);
  });

  it('Возвращает корректное значние и не изменяет свойства game при неверном значении времени', () => {
    const levels = [[[1]]];
    const game = new Game(levels);
    const ballX = game.ball.x;
    const ballY = game.ball.y;
    expect(tick(game, 1, 1, -1)).toBeNull();
    expect(game.ball.x).toBe(ballX);
    expect(game.ball.y).toBe(ballY);
  });

  it('Меняет направление мяча при столкновении со стеной', () => {
    const levels = [[[1]]];
    const game = new Game(levels);
    game.ball.x = 0;
    game.ball.horizontalSpeed = -10;
    tick(game, CONTAINER_WIDTH, CONTAINER_HEIGHT, 1);
    expect(game.ball.x).toBe(10);
    expect(game.ball.horizontalSpeed).toBe(10);
  });

  it('Меняет направление мяча при столкновении с потолком', () => {
    const levels = [[[1]]];
    const game = new Game(1);
    game.ball.y = 0;
    game.ball.verticalSpeed = -10;
    tick(game, CONTAINER_WIDTH, CONTAINER_HEIGHT, 1);
    expect(game.ball.y).toBe(game.ball.radius);
    expect(game.ball.verticalSpeed).toBe(10);
  });

  it('Убивает кирпич при столкновении и отражает мяч', () => {
    const levels = [[[1]]];
    const game = new Game(levels);
    const brick = game.bricks[0];

    game.ball.x = brick.x + game.ball.radius + 1;
    game.ball.y = brick.y + brick.height + game.ball.radius + 1;
    game.ball.horizontalSpeed = 0;
    game.ball.verticalSpeed = -10;

    tick(game, CONTAINER_WIDTH, CONTAINER_HEIGHT, 0.1);

    expect(brick.alive).toBe(false);
    expect(game.ball.verticalSpeed).toBe(10);
  });

  it('Убивает только один кирпич за тик', () => {
    const levels = [[[1, 1]]];
    const game = new Game(levels);
    const [firstBrick, secondBrick] = game.bricks;

    game.ball.x = firstBrick.x + game.ball.radius + 1;
    game.ball.y = firstBrick.y + firstBrick.height + game.ball.radius + 1;
    game.ball.horizontalSpeed = 0;
    game.ball.verticalSpeed = -10;

    tick(game, CONTAINER_WIDTH, CONTAINER_HEIGHT, 0.1);

    const killedCount = game.bricks.filter((b) => !b.alive).length;
    expect(killedCount).toBe(1);
  });
});
