// AudioEngine.h

#pragma once
#include "miniaudio.h"
#include <cstdint>
#include <string>
#include <vector>
#include <unordered_map>
#include "../utils/AssetManager.h"
#include "../utils/Logging.h"

struct PlayingInfo
{
    uint64_t uaid;
    std::string name;
    double currentTime = 0.0;
    double totalTime = 0.0;
    bool looping = false;
    bool hasStarted = false;
    ma_sound *sound = nullptr;
    float vuLeft = 0.0f;
    float vuRight = 0.0f;
};

class AudioEngine
{
public:
    static bool Init();
    static void Shutdown();
    static void Play(uint64_t uaid, bool loop = false);
    static void Stop(uint64_t uaid);
    static void StopAll();
    static void Unload(uint64_t uaid);
    static void Update();
    static void SetVolume(uint64_t uaid, float volume);
    static void SetLooping(uint64_t uaid, bool loop);

    static ma_engine* GetEngine() { return &s_Engine; }

    static const std::vector<float> &GetMasterVU();

    static const std::unordered_map<uint64_t, PlayingInfo> &GetPlayingInfoMap();

private:
    static ma_engine s_Engine;
    static std::unordered_map<uint64_t, ma_sound *> s_SoundMap;
    static std::unordered_map<uint64_t, PlayingInfo> s_PlayingInfoMap;

    // Per-channel master peaks
    static std::vector<float> s_MasterVU;

    static void CleanupSound(uint64_t uaid);

    static void EngineProcessCallback(
        void *pUserData,
        float *pFramesOut,
        ma_uint64 frameCount);

    static void Cleanup(uint64_t uaid);
};
