import 'package:flutter_soloud/flutter_soloud.dart';
import 'package:wolf_3d_data_types/wolf_3d_data_types.dart';
import 'package:wolf_3d_synth/src/imf_renderer.dart';

class WolfAudio {
  bool _isInitialized = false;

  // --- Music State ---
  AudioSource? _currentMusicSource;
  SoundHandle? _currentMusicHandle;

  WolfensteinData? activeGame;

  /// Initializes the SoLoud audio engine.
  Future<void> init() async {
    if (_isInitialized) return;

    try {
      await SoLoud.instance.init(
        sampleRate: 44100,
        bufferSize: 2048,
        channels: Channels.stereo,
      );
      _isInitialized = true;
      print("WolfAudio: SoLoud initialized successfully.");
    } catch (e) {
      print("WolfAudio: Failed to initialize SoLoud - $e");
    }
  }

  /// Disposes of the audio engine and frees resources.
  void dispose() {
    stopMusic();
    SoLoud.instance.deinit();
    _isInitialized = false;
  }

  // ==========================================
  // MUSIC MANAGEMENT
  // ==========================================

  /// Renders and plays a specific IMF music track.
  Future<void> playMusic(ImfMusic track, {bool looping = true}) async {
    if (!_isInitialized) return;

    // Stop currently playing music to prevent overlap
    stopMusic();

    try {
      // Render hardware instructions into PCM and wrap in WAV
      final pcmSamples = ImfRenderer.render(track);
      final wavBytes = ImfRenderer.createWavFile(pcmSamples);

      _currentMusicSource = await SoLoud.instance.loadMem(
        'track.wav',
        wavBytes,
      );
      _currentMusicHandle = await SoLoud.instance.play(
        _currentMusicSource!,
        looping: looping,
      );
    } catch (e) {
      print("WolfAudio: Error playing music track - $e");
    }
  }

  /// Halts playback and frees memory for the current track.
  void stopMusic() {
    if (!_isInitialized) return;

    if (_currentMusicHandle != null) {
      SoLoud.instance.stop(_currentMusicHandle!);
      _currentMusicHandle = null;
    }
    if (_currentMusicSource != null) {
      SoLoud.instance.disposeSource(_currentMusicSource!);
      _currentMusicSource = null;
    }
  }

  /// Pauses the current track.
  void pauseMusic() {
    if (_isInitialized && _currentMusicHandle != null) {
      SoLoud.instance.setPause(_currentMusicHandle!, true);
    }
  }

  /// Resumes a paused track.
  void resumeMusic() {
    if (_isInitialized && _currentMusicHandle != null) {
      SoLoud.instance.setPause(_currentMusicHandle!, false);
    }
  }

  Future<void> playMenuMusic() async {
    final data = activeGame;
    // We can't play if data isn't set or doesn't have enough tracks
    if (data == null || data.music.length <= 1) return;

    // Track 1 is the menu theme in both Shareware and Retail
    await playMusic(data.music[1]);
  }

  /// Plays the specific track assigned to a WolfLevel.
  Future<void> playLevelMusic(WolfLevel level) async {
    final data = activeGame;
    if (data == null || data.music.isEmpty) return;

    final index = level.musicIndex;

    if (index < data.music.length) {
      // 3. FIXED THIS: Call your playMusic method
      await playMusic(data.music[index]);
    } else {
      print(
        "WolfAudio: Warning - Track index $index out of bounds for level ${level.name}.",
      );
    }
  }
}
