#pragma once

#include <juce_audio_basics/juce_audio_basics.h>

#include <array>

namespace deeppluck
{
class DeepPluckFilter final
{
public:
    void prepare (double newSampleRate) noexcept;
    void reset() noexcept;
    void setCutoffFrequencyHz (float newCutoffHz) noexcept;
    void setResonance (float newResonance) noexcept;
    void setDriveDb (float newDriveDb) noexcept;
    [[nodiscard]] float processSample (float input) noexcept;

    [[nodiscard]] float getCutoffFrequencyHz() const noexcept { return cutoffHz; }
    [[nodiscard]] float getResonance() const noexcept { return resonance; }
    [[nodiscard]] float getDriveDb() const noexcept { return driveDb; }
    [[nodiscard]] float getCurrentResonanceCompensation() const noexcept
    {
        return resonanceCompensation.getCurrentValue();
    }
    [[nodiscard]] float getTargetResonanceCompensation() const noexcept
    {
        return resonanceCompensation.getTargetValue();
    }

private:
    [[nodiscard]] float saturateInput (float input) noexcept;

    std::array<float, 5> state {};
    double sampleRate = 44100.0;
    float cutoffHz = 1800.0f;
    float resonance = 0.18f;
    float driveDb = 3.0f;
    juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> driveShape;
    juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear>
        resonanceCompensation { 1.0f };
};
}
