#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>

#include "platform/sound_effects.hpp"

#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")

namespace poe2::platform {

SoundEffects::SoundEffects() {
    worker_ = std::thread(&SoundEffects::WorkerLoop, this);
}

SoundEffects::~SoundEffects() {
    Stop();
}

void SoundEffects::Stop() {
    if (!running_.exchange(false)) return;
    cv_.notify_all();
    if (worker_.joinable()) {
        worker_.join();
    }
}

void SoundEffects::EnqueueSound(SoundType type) {
    if (!IsEnabled() || !running_.load(std::memory_order_relaxed)) return;
    {
        std::lock_guard<std::mutex> lock(mutex_);
        // Limit queue size to 4 to prevent lag/overflow when keys are spammed
        if (queue_.size() < 4) {
            queue_.push(type);
            cv_.notify_one();
        }
    }
}

void SoundEffects::PlayAttachSuccess() {
    EnqueueSound(SoundType::AttachSuccess);
}

void SoundEffects::PlayPanicRestore() {
    EnqueueSound(SoundType::PanicRestore);
}

void SoundEffects::PlayBrickAlert() {
    EnqueueSound(SoundType::BrickAlert);
}

void SoundEffects::PlayToggle(bool isOn) {
    EnqueueSound(isOn ? SoundType::ToggleOn : SoundType::ToggleOff);
}

void SoundEffects::WorkerLoop() {
    while (running_.load(std::memory_order_relaxed)) {
        SoundType sound;
        {
            std::unique_lock<std::mutex> lock(mutex_);
            cv_.wait(lock, [this] {
                return !queue_.empty() || !running_.load(std::memory_order_relaxed);
            });
            if (!running_.load(std::memory_order_relaxed) && queue_.empty()) {
                break;
            }
            if (queue_.empty()) continue;
            sound = queue_.front();
            queue_.pop();
        }

        switch (sound) {
            case SoundType::AttachSuccess:
                Beep(523, 70);
                Beep(659, 120);
                break;
            case SoundType::PanicRestore:
                Beep(880, 80);
                Beep(440, 160);
                break;
            case SoundType::BrickAlert:
                Beep(1046, 60);
                Beep(880, 60);
                Beep(1046, 120);
                break;
            case SoundType::ToggleOn:
                Beep(784, 40);
                break;
            case SoundType::ToggleOff:
                Beep(494, 40);
                break;
        }
    }
}

} // namespace poe2::platform

