// Audio.h - MP3 playlist playback (Windows Media Foundation backend) + SDL3 stream
#pragma once
#include <SDL3/SDL.h>
#include <vector>
#include <string>
#include <random>
#include <cstdint>
#include <thread>
#include <mutex>
#include <atomic>
#include "../core/interfaces/IAudioSystem.h"

struct AudioTrack {
    std::string path;
    std::vector<int16_t> pcm;
    int channels = 2;
    int rate = 44100;
    size_t cursor = 0;
    bool ok = false;
};

class Audio : public IAudioSystem {
public:
    static Audio& instance();
    
    // IAudioSystem interface implementation
    void playSound(const std::string& name) override;
    void playMusic(const std::string& name) override;
    void stopMusic() override;
    void setMasterVolume(float volume) override;
    void setMusicVolume(float volume) override;
    void setSoundVolume(float volume) override;
    bool isMusicPlaying() const override;

    // Existing Audio class methods
    bool init();                  // initialize backend (MF on Windows)
    void addTrack(const std::string& path); // decode MP3 -> PCM16 stereo 44100
    void addTrackAsync(const std::string& path); // add track for background loading
    void startBackgroundLoading(); // start background thread for loading
    void waitForLoadingComplete(); // wait for all tracks to finish loading
    bool isLoadingComplete() const; // check if background loading is done
    int getLoadedTrackCount() const; // get number of tracks loaded so far
    void shuffle();               // randomize order
    void start();                 // begin playback
    void skipToNextTrack();       // advance to the next music track
    void toggleMute();
    void setMuted(bool m);
    bool isMuted() const { return muted; }
    
    // Menu music support
    void setMenuTrack(const std::string& path);
    void playMenuMusic();
    void playGameMusic();
    
    // Queue a sound effect to mix over the music (pcm can be mono/stereo, any rate; will be converted)
    void playSfx(const std::vector<int16_t>& pcm, int channels, int rate, float volume);
    void shutdown();
private:
    Audio()=default; ~Audio()=default; Audio(const Audio&)=delete; Audio& operator=(const Audio&)=delete;
    static void SDLCALL streamCallback(void* userdata, SDL_AudioStream* stream, int additional, int total);
    void feed(Uint32 bytesWanted, SDL_AudioStream* stream);
    void nextTrack();
    bool ensureStream();
    void backgroundLoadingThread(); // background thread function
    
    std::vector<AudioTrack> tracks; 
    AudioTrack menuTrack;
    bool isMenuMusic = false;
    int current=-1; bool playing=false; bool muted=false; std::mt19937 rng{std::random_device{}()};
    SDL_AudioStream* audioStream=nullptr; SDL_AudioSpec outSpec{}; int outChannels=2; int outRate=44100; bool mfStarted=false;
    
    // Threading support
    std::vector<std::string> pendingTracks;
    std::thread loadingThread;
    std::mutex tracksMutex;
    std::mutex pendingTracksMutex;
    std::atomic<bool> loadingComplete{false};
    std::atomic<bool> loadingAbort{false};
    std::atomic<int> loadedCount{0};

    // SFX mixing support
    struct SfxPlay { std::vector<int16_t> pcm; size_t cursor=0; };
    std::vector<SfxPlay> activeSfx;
    std::mutex sfxMutex;
    
    // Volume control
    float m_masterVolume = 1.0f;
    float m_musicVolume = 1.0f;
    float m_sfxVolume = 1.0f;
};
