import 'package:asciineverdie/src/core/engine/progress_loop.dart';
import 'package:asciineverdie/src/core/model/combat_state.dart';
import 'package:asciineverdie/src/core/model/combat_stats.dart';
import 'package:asciineverdie/src/core/model/game_state.dart';
import 'package:asciineverdie/src/core/model/monster_combat_stats.dart';
import 'package:asciineverdie/src/core/util/balance_constants.dart';
import 'package:flutter_test/flutter_test.dart';

import '../../helpers/mock_factories.dart';

void main() {
  late final service = MockFactories.createProgressService();

  test('autosaves on level-up and stop when configured', () async {
    final saveManager = FakeSaveManager();

    // 레벨 1에서 레벨업에 필요한 경험치
    final requiredExp = ExpConstants.requiredExp(1);

    // 레벨업에 충분한 경험치를 주는 몬스터 (사망 상태)
    final monsterStats = MonsterCombatStats(
      name: 'Test Monster',
      level: 1,
      atk: 10,
      def: 5,
      magDef: 5,
      hpMax: 50,
      hpCurrent: 0, // 몬스터 사망
      criRate: 0.05,
      criDamage: 1.5,
      evasion: 0.0,
      accuracy: 0.8,
      attackDelayMs: 1000,
      expReward: requiredExp + 100, // 레벨업에 충분한 경험치
    );

    final combatState = CombatState(
      playerStats: CombatStats.empty(),
      monsterStats: monsterStats,
      playerAttackAccumulatorMs: 0,
      monsterAttackAccumulatorMs: 0,
      totalDamageDealt: 50,
      totalDamageTaken: 0,
      turnsElapsed: 1,
      isActive: true,
    );

    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: ProgressState(
        task: const ProgressBarState(position: 1200, max: 1200),
        quest: const ProgressBarState(position: 0, max: 10),
        plot: const ProgressBarState(position: 0, max: 10),
        exp: ProgressBarState(position: requiredExp - 50, max: requiredExp),
        encumbrance: const ProgressBarState(position: 0, max: 0),
        currentTask: const TaskInfo(caption: 'Battle', type: TaskType.kill),
        plotStageCount: 1,
        questCount: 0,
        currentCombat: combatState,
      ),
    );

    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));
  });
}
