import 'package:block_seasons/game/engine/scoring.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('lineClearBase', () {
    test('escalates with simultaneous lines', () {
      expect(lineClearBase(1), 100);
      expect(lineClearBase(2), 300);
      expect(lineClearBase(3), 600);
      expect(lineClearBase(4), 1000);
    });
  });

  group('comboMultiplier', () {
    test('grows by 0.5 per streak step and caps at 8', () {
      expect(comboMultiplier(1), 1.5);
      expect(comboMultiplier(2), 2.0);
      expect(comboMultiplier(8), 5.0);
      expect(comboMultiplier(12), 5.0);
    });
  });

  group('ComboState', () {
    test('clearing placements grow the streak', () {
      var combo = ComboState.initial;
      combo = combo.advance(cleared: true);
      expect(combo.streak, 1);
      combo = combo.advance(cleared: true);
      expect(combo.streak, 2);
    });

    test('one dry move is grace, streak survives', () {
      var combo = ComboState.initial;
      combo = combo.advance(cleared: true);
      combo = combo.advance(cleared: false);
      expect(combo.streak, 1);
      combo = combo.advance(cleared: true);
      expect(combo.streak, 2);
    });

    test('two consecutive dry moves reset the streak', () {
      var combo = ComboState.initial;
      combo = combo.advance(cleared: true);
      combo = combo.advance(cleared: false);
      combo = combo.advance(cleared: false);
      expect(combo.streak, 0);
      combo = combo.advance(cleared: true);
      expect(combo.streak, 1);
    });
  });

  group('scorePlacement', () {
    test('placement without clear scores cell count only', () {
      final delta = scorePlacement(
        cellsPlaced: 4,
        linesCleared: 0,
        combo: ComboState.initial,
      );
      expect(delta.points, 4);
      expect(delta.combo.streak, 0);
    });

    test('first clear applies x1.5 multiplier', () {
      final delta = scorePlacement(
        cellsPlaced: 5,
        linesCleared: 1,
        combo: ComboState.initial,
      );
      // 5 + round(100 * 1.5) = 155
      expect(delta.points, 155);
      expect(delta.combo.streak, 1);
    });

    test('streak compounds across placements', () {
      var combo = ComboState.initial;
      final first = scorePlacement(
        cellsPlaced: 3,
        linesCleared: 1,
        combo: combo,
      );
      combo = first.combo;
      final second = scorePlacement(
        cellsPlaced: 3,
        linesCleared: 2,
        combo: combo,
      );
      // 3 + round(300 * 2.0) = 603
      expect(second.points, 603);
      expect(second.combo.streak, 2);
    });
  });
}
