#pragma once
#include "PluginProcessor.h"
#include <juce_audio_processors/juce_audio_processors.h>

class SaftpumpeEditor : public juce::AudioProcessorEditor,
                         public juce::Timer,
                         public juce::ComboBox::Listener {
public:
    SaftpumpeEditor(SaftpumpeProcessor&);
    ~SaftpumpeEditor() override;

    void paint(juce::Graphics&) override;
    void resized() override;
    void timerCallback() override;
    void comboBoxChanged(juce::ComboBox* box) override;

private:
    SaftpumpeProcessor& processorRef;

    float uiScale = 1.5f;

    // Dark industrial palette
    juce::Colour bezelColour{0xff0a0a0c};
    juce::Colour faceplateTop{0xff222226};
    juce::Colour faceplateBot{0xff161618};
    juce::Colour knobLight{0xff72727a};
    juce::Colour knobDark{0xff3a3a40};
    juce::Colour grooveDark{0xff111114};
    juce::Colour greenLed{0xff00e676};
    juce::Colour redLed{0xffe63333};
    juce::Colour amberLed{0xffe6a600};
    juce::Colour textColour{0xffb0b0b6};
    juce::Colour textDim{0xff6a6a70};
    juce::Colour textBright{0xffe0e0e4};
    juce::Colour accentLine{0xff00e676};
    juce::Colour lcdBg{0xff080c08};
    juce::Colour lcdText{0xff00cc66};

    juce::Slider thresholdSlider, ratioSlider, attackSlider, releaseSlider;
    juce::Slider kneeSlider, makeupSlider, mixSlider, autoReleaseSlider;

    juce::Label thresholdLabel, ratioLabel, attackLabel, releaseLabel;
    juce::Label kneeLabel, makeupLabel, mixLabel, autoReleaseLabel;

    // LCD value displays
    juce::Label thresholdLCD, ratioLCD, attackLCD, releaseLCD;
    juce::Label kneeLCD, makeupLCD, mixLCD, autoReleaseLCD;

    juce::ComboBox zoomBox;
    juce::Label zoomLabel;
    juce::ComboBox presetBox;
    juce::Label presetLabel;

    using SliderAttachment = juce::AudioProcessorValueTreeState::SliderAttachment;

    std::unique_ptr<SliderAttachment> thresholdAttachment, ratioAttachment, attackAttachment;
    std::unique_ptr<SliderAttachment> releaseAttachment, kneeAttachment, makeupAttachment;
    std::unique_ptr<SliderAttachment> mixAttachment, autoReleaseAttachment;

    juce::Rectangle<float> meterArea;
    juce::Rectangle<float> scopeArea;
    juce::Rectangle<float> zoomArea;
    juce::Rectangle<float> rowBounds[2];
    juce::Rectangle<float> knobBounds[8];
    juce::Point<float> knobCentre[8];
    float knobRadius = 0.0f;

    struct PeakHold {
        float peak = 0.0f;
        double peakTime = 0.0;
        static constexpr double holdMs = 1000.0;
    } grPeak, inPeak, outPeak;

    void computeLayout();
    void drawKnob(juce::Graphics& g, juce::Rectangle<float> bounds, float normalizedValue,
                  float arcFillFrac);
    void drawLCD(juce::Graphics& g, juce::Rectangle<float> bounds, const juce::String& text);
    void drawMeter(juce::Graphics& g, juce::Rectangle<float> bounds,
                   float level, float minDb, float maxDb, bool isGainReduction);
    void drawPeakHold(juce::Graphics& g, juce::Rectangle<float> bounds,
                       float peakNorm, bool fromTop = false);
    void drawScope(juce::Graphics& g, juce::Rectangle<float> bounds);
    void drawScrew(juce::Graphics& g, float cx, float cy, float radius);

    static constexpr float startAngle = juce::MathConstants<float>::pi * 0.75f;
    static constexpr float endAngle   = juce::MathConstants<float>::pi * 2.25f;

    juce::String formatValue(int idx, float val);

    struct Preset {
        const char* name;
        float threshold, ratio, attack, release, knee, makeup, mix, autoRelease;
    };
    static const std::vector<Preset>& getPresets();
    void applyPreset(int index);

    juce::Rectangle<float> presetArea;

    struct NoDotLookAndFeel : juce::LookAndFeel_V4 {
        void drawRotarySlider(juce::Graphics&, int, int, int, int,
                              float, float, float, juce::Slider&) override {}
    } lnf;

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SaftpumpeEditor)
};
