import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
import 'package:wolf_3d_dart/wolf_3d_engine.dart';
import 'package:wolf_3d_flutter/wolf_3d_flutter.dart';
import 'package:wolf_3d_gui/screens/game_screen.dart';

class _CountingAudio implements EngineAudio {
  @override
  WolfensteinData? activeGame;

  int stopAllAudioCallCount = 0;
  int disposeCallCount = 0;

  @override
  Future<void> debugSoundTest() async {}

  @override
  Future<void> init() async {}

  @override
  void playLevelMusic(Music music) {}

  @override
  void playMenuMusic() {}

  @override
  void playSoundEffect(SoundEffect effect) {}

  @override
  void playSoundEffectId(int sfxId) {}

  @override
  Future<void> stopAllAudio() async {
    stopAllAudioCallCount++;
    await Future<void>.delayed(const Duration(milliseconds: 1));
  }

  @override
  void stopMusic() {}

  @override
  void dispose() {
    disposeCallCount++;
  }
}

void main() {
  testWidgets('quit path shuts down audio once and exits once', (tester) async {
    final audio = _CountingAudio();
    final wolf3d = Wolf3d(audioBackend: audio);
    int appExitCallCount = 0;

    await tester.pumpWidget(
      MaterialApp(
        home: GameScreen(
          wolf3d: wolf3d,
          skipEngineBootstrapForTest: true,
          triggerQuitOnInitForTest: true,
          appExitHandler: () async {
            appExitCallCount++;
          },
        ),
      ),
    );
    await tester.pump(const Duration(milliseconds: 10));

    expect(audio.stopAllAudioCallCount, 1);
    expect(audio.disposeCallCount, 1);
    expect(appExitCallCount, 1);
  });

  testWidgets('dispose path shuts down audio', (tester) async {
    final audio = _CountingAudio();
    final wolf3d = Wolf3d(audioBackend: audio);

    await tester.pumpWidget(
      MaterialApp(
        home: GameScreen(
          wolf3d: wolf3d,
          skipEngineBootstrapForTest: true,
          appExitHandler: () async {},
        ),
      ),
    );

    await tester.pumpWidget(const MaterialApp(home: SizedBox.shrink()));
    await tester.pump(const Duration(milliseconds: 10));

    expect(audio.stopAllAudioCallCount, 1);
    expect(audio.disposeCallCount, 1);
  });
}
