import 'package:block_seasons/data/save_repository.dart';
import 'package:block_seasons/data/streak.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('advanceStreak', () {
    test('first ever play starts the streak at 1', () {
      final next = advanceStreak(StreakState.initial, DateTime(2026, 6, 11));
      expect(next.current, 1);
      expect(next.best, 1);
      expect(next.lastYmd, '2026-06-11');
    });

    test('same-day repeat play changes nothing', () {
      final day1 = advanceStreak(StreakState.initial, DateTime(2026, 6, 11));
      final again = advanceStreak(day1, DateTime(2026, 6, 11, 23, 59));
      expect(again.current, 1);
      expect(again.best, 1);
    });

    test('consecutive days grow the streak and best follows', () {
      var s = advanceStreak(StreakState.initial, DateTime(2026, 6, 11));
      s = advanceStreak(s, DateTime(2026, 6, 12));
      s = advanceStreak(s, DateTime(2026, 6, 13));
      expect(s.current, 3);
      expect(s.best, 3);
    });

    test('missing a day resets current but keeps best', () {
      var s = advanceStreak(StreakState.initial, DateTime(2026, 6, 11));
      s = advanceStreak(s, DateTime(2026, 6, 12));
      s = advanceStreak(s, DateTime(2026, 6, 15));
      expect(s.current, 1);
      expect(s.best, 2);
    });

    test('month boundaries count as consecutive days', () {
      var s = advanceStreak(StreakState.initial, DateTime(2026, 6, 30));
      s = advanceStreak(s, DateTime(2026, 7, 1));
      expect(s.current, 2);
    });

    test('milestone crossings are flagged once', () {
      var s = StreakState(current: 2, best: 6, lastYmd: '2026-06-10');
      final next = advanceStreak(s, DateTime(2026, 6, 11));
      expect(next.current, 3);
      expect(next.hitMilestone, 3);

      s = StreakState(current: 3, best: 6, lastYmd: '2026-06-11');
      final after = advanceStreak(s, DateTime(2026, 6, 12));
      expect(after.hitMilestone, isNull, reason: '4 is not a milestone');
    });
  });

  group('SaveRepository streak persistence', () {
    test('round-trips streak state', () async {
      SharedPreferences.setMockInitialValues({});
      final prefs = await SharedPreferences.getInstance();
      final repo = SaveRepository(prefs);
      expect(repo.streak.current, 0);

      await repo.saveStreak(
        const StreakState(current: 5, best: 9, lastYmd: '2026-06-11'),
      );
      final reloaded = SaveRepository(prefs);
      expect(reloaded.streak.current, 5);
      expect(reloaded.streak.best, 9);
      expect(reloaded.streak.lastYmd, '2026-06-11');
    });
  });
}
