#pragma once

#ifndef NOMINMAX
#define NOMINMAX
#endif

#include <cstdint>
#include <memory>

#include "memory/imemory_reader.hpp"

namespace visual {

struct ReducerConfig {
    bool disableWeather = true;
    bool disableScreenShake = true;
    bool reduceBloom = true;
    float targetBloomScale = 0.15f; // reduced from 1.0f default
};

class ParticleReducer {
public:
    explicit ParticleReducer(IMemoryReader& memory);
    ~ParticleReducer();

    void SetAddresses(
        uintptr_t weatherParticleAddr,
        uintptr_t screenShakeAddr,
        uintptr_t bloomScaleAddr
    );

    uintptr_t WeatherAddress() const { return weatherParticleAddr_; }
    uintptr_t ScreenShakeAddress() const { return screenShakeAddr_; }
    uintptr_t BloomAddress() const { return bloomScaleAddr_; }

    bool ApplyOptimizations(const ReducerConfig& config);
    bool RestoreAll();
    void PanicRestoreAll();

    bool IsActive() const { return isActive_; }

    float OrigWeatherDensity() const { return origWeatherDensity_; }
    uint8_t OrigScreenShake() const { return origScreenShake_; }
    float OrigBloomScale() const { return origBloomScale_; }

private:
    IMemoryReader& memory_;
    uintptr_t weatherParticleAddr_ = 0;
    uintptr_t screenShakeAddr_ = 0;
    uintptr_t bloomScaleAddr_ = 0;

    float origWeatherDensity_ = 1.0f;
    uint8_t origScreenShake_ = 1;
    float origBloomScale_ = 1.0f;

    bool origValuesCaptured_ = false;
    bool isActive_ = false;
};

} // namespace visual
