import 'package:askiineverdie/src/core/engine/game_mutations.dart';
import 'package:askiineverdie/src/core/engine/progress_loop.dart';
import 'package:askiineverdie/src/core/engine/progress_service.dart';
import 'package:askiineverdie/src/core/engine/reward_service.dart';
import 'package:askiineverdie/src/core/model/game_state.dart';
import 'package:askiineverdie/src/core/model/pq_config.dart';
import 'package:askiineverdie/src/core/storage/save_manager.dart';
import 'package:askiineverdie/src/core/storage/save_repository.dart';
import 'package:askiineverdie/src/core/storage/save_service.dart';
import 'package:flutter_test/flutter_test.dart';

class _FakeSaveManager implements SaveManager {
  final List<GameState> savedStates = [];

  @override
  Future<SaveOutcome> saveState(GameState state, {String? fileName}) async {
    savedStates.add(state);
    return const SaveOutcome.success();
  }

  @override
  Future<(SaveOutcome, GameState?)> loadState({String? fileName}) async {
    return (const SaveOutcome.success(), null);
  }

  @override
  Future<List<SaveFileInfo>> listSaves() async => [];

  @override
  Future<SaveOutcome> deleteSave({String? fileName}) async {
    return const SaveOutcome.success();
  }

  @override
  Future<bool> saveExists({String? fileName}) async => false;
}

void main() {
  late ProgressService service;

  setUp(() {
    const config = PqConfig();
    final mutations = GameMutations(config);
    service = ProgressService(
      config: config,
      mutations: mutations,
      rewards: RewardService(mutations),
    );
  });

  test('autosaves on level-up and stop when configured', () async {
    final saveManager = _FakeSaveManager();
    final initial = GameState.withSeed(
      seed: 123,
      traits: const Traits(
        name: 'LoopHero',
        race: 'Orc',
        klass: 'Warrior',
        level: 1,
        motto: '',
        guild: '',
      ),
      stats: const Stats(
        str: 8,
        con: 7,
        dex: 6,
        intelligence: 5,
        wis: 4,
        cha: 3,
        hpMax: 9,
        mpMax: 8,
      ),
      progress: const ProgressState(
        task: ProgressBarState(position: 1200, max: 1200),
        quest: ProgressBarState(position: 0, max: 10),
        plot: ProgressBarState(position: 0, max: 10),
        exp: ProgressBarState(position: 3, max: 3),
        encumbrance: ProgressBarState(position: 0, max: 0),
        currentTask: TaskInfo(caption: 'Battle', type: TaskType.kill),
        plotStageCount: 1,
        questCount: 0,
      ),
    );

    final loop = ProgressLoop(
      initialState: initial,
      progressService: service,
      saveManager: saveManager,
      autoSaveConfig: const AutoSaveConfig(
        onLevelUp: true,
        onQuestComplete: true,
        onActComplete: true,
        onStop: true,
      ),
      now: () => DateTime.fromMillisecondsSinceEpoch(0),
    );

    final updated = loop.tickOnce(deltaMillis: 50);

    expect(saveManager.savedStates.length, 1);
    expect(updated.traits.level, 2);

    await loop.stop(saveOnStop: true);

    expect(saveManager.savedStates.length, 2);
    expect(saveManager.savedStates.last, same(updated));
  });
}
