import 'package:block_seasons/game/engine/game_event.dart';
import 'package:block_seasons/game/models/objective.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('ClearGems', () {
    test('accumulates gems from clear events', () {
      var obj = Objective.clearGems(6);
      obj = obj.onEvent(const LinesCleared(lines: 1, gems: 2));
      obj = obj.onEvent(const LinesCleared(lines: 2, gems: 3));
      expect(obj.current, 5);
      expect(obj.isComplete, isFalse);
      obj = obj.onEvent(const LinesCleared(lines: 1, gems: 1));
      expect(obj.isComplete, isTrue);
    });

    test('ignores unrelated events', () {
      var obj = Objective.clearGems(3);
      obj = obj.onEvent(const ScoreChanged(total: 9999));
      expect(obj.current, 0);
    });
  });

  group('ReachScore', () {
    test('tracks the running total score', () {
      var obj = Objective.reachScore(500);
      obj = obj.onEvent(const ScoreChanged(total: 320));
      expect(obj.current, 320);
      expect(obj.isComplete, isFalse);
      obj = obj.onEvent(const ScoreChanged(total: 510));
      expect(obj.isComplete, isTrue);
    });
  });

  group('ClearLines', () {
    test('accumulates cleared lines', () {
      var obj = Objective.clearLines(4);
      obj = obj.onEvent(const LinesCleared(lines: 3, gems: 0));
      expect(obj.current, 3);
      obj = obj.onEvent(const LinesCleared(lines: 1, gems: 0));
      expect(obj.isComplete, isTrue);
    });
  });

  group('JSON', () {
    test('round-trips all objective types', () {
      for (final json in [
        {'type': 'clearGems', 'count': 6},
        {'type': 'reachScore', 'target': 1200},
        {'type': 'clearLines', 'count': 10},
      ]) {
        final obj = Objective.fromJson(json);
        expect(obj.toJson(), json);
        expect(obj.current, 0);
        expect(obj.target, greaterThan(0));
      }
    });

    test('throws on unknown type', () {
      expect(
        () => Objective.fromJson({'type': 'collectStars', 'count': 1}),
        throwsFormatException,
      );
    });
  });
}
