import 'package:block_seasons/data/save_repository.dart';
import 'package:block_seasons/game/engine/game_engine.dart';
import 'package:block_seasons/game/models/season.dart';
import 'package:block_seasons/state/providers.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';

SeasonPack _pack() => SeasonPack.fromJson({
      'schemaVersion': 1,
      'seasonId': 'season_test',
      'version': 1,
      'title': {'en': 'T', 'ko': 'T'},
      'theme': {'tileSet': 'spring', 'background': 'bg.webp'},
      'stages': [
        for (var i = 0; i < 3; i++)
          {
            'id': 'st_$i',
            'seed': 100 + i,
            'moveLimit': 20,
            'preset': const <Map<String, dynamic>>[],
            'objectives': [
              {'type': 'reachScore', 'target': 999999},
            ],
            'stars': {
              'two': {'movesLeft': 5},
              'three': {'movesLeft': 10},
            },
            'generatorProfile': 'mid',
          },
      ],
    });

Future<ProviderContainer> _container() async {
  SharedPreferences.setMockInitialValues({});
  final repo = SaveRepository(await SharedPreferences.getInstance());
  final container = ProviderContainer(
    overrides: [saveRepositoryProvider.overrideWithValue(repo)],
  );
  addTearDown(container.dispose);
  return container;
}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  test('starting a season stage spins up the game session', () async {
    final container = await _container();
    final flow = container.read(seasonFlowProvider.notifier);
    flow.startSeasonStage(_pack(), 0);

    expect(container.read(seasonFlowProvider)!.index, 0);
    expect(container.read(seasonFlowProvider)!.hasNext, isTrue);
    final session = container.read(gameSessionProvider)!;
    expect(session.phase, GamePhase.playing);
    expect(session.movesLeft, 20);
  });

  test('recordWin persists stars through the progress notifier', () async {
    final container = await _container();
    final flow = container.read(seasonFlowProvider.notifier);
    flow.startSeasonStage(_pack(), 1);
    await flow.recordWin(stars: 3, score: 1234);

    final repo = container.read(saveRepositoryProvider);
    expect(repo.progressFor('season_test', 'st_1')!.stars, 3);
    expect(container.read(progressProvider)['season_test/st_1']!.stars, 3);
  });

  test('nextStage advances and starts the following stage', () async {
    final container = await _container();
    final flow = container.read(seasonFlowProvider.notifier);
    flow.startSeasonStage(_pack(), 1);
    flow.nextStage();

    expect(container.read(seasonFlowProvider)!.index, 2);
    expect(container.read(seasonFlowProvider)!.hasNext, isFalse);
    expect(container.read(gameSessionProvider)!.phase, GamePhase.playing);
  });

  test('clear() resets flow to null so Classic mode has no stale season context',
      () async {
    final container = await _container();
    final flow = container.read(seasonFlowProvider.notifier);
    flow.startSeasonStage(_pack(), 0);

    // State is non-null after starting a season stage.
    expect(container.read(seasonFlowProvider), isNotNull);

    flow.clear();

    // After clear(), the flow must be null so GameScreen's tutorial/theme
    // checks can't fire for a Classic (endless) session.
    expect(container.read(seasonFlowProvider), isNull);
  });
}
