// 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;

    // Additional IAudioSystem methods (forwarded to concrete implementation)
    bool init() override;
    void shutdown() override;
    void addTrack(const std::string& path) override;
    void addTrackAsync(const std::string& path) override;
    void startBackgroundLoading() override;
    bool isLoadingComplete() const override;
    int getLoadedTrackCount() const override;
    void start() override;
    void skipToNextTrack() override;
    void shuffle() override;
    void toggleMute() override;
    bool isMuted() const override;
    void setMuted(bool m);
    void setMenuTrack(const std::string& path) override;
    void playMenuMusic() override;
    void playGameMusic() override;
    void playSfx(const std::vector<int16_t>& pcm, int channels, int rate, float volume) override;

    // Existing Audio class helper methods
    void waitForLoadingComplete(); // wait for all tracks to finish loading
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;
};
