// Copyright (c) 2026 Ourpad Network
// See LICENSE file in the project root for full license text.

#pragma once

#include <memory>
#include <vector>
#include <atomic>
#include <string>
#include "mixer/Types.hpp"

namespace mixer {

/// A single channel strip in the mixer.
///
/// Each MixerChannelStrip wraps:
///   - Volume fader, pan pot, mute, solo
///   - High-pass filter on input
///   - Aux sends (pre/post fader)
///   - VU metering
///
/// The channel operates in the real-time audio thread.
/// Control changes are made from the non-realtime thread via atomic snapshots.
class MixerChannelStrip {
public:
    MixerChannelStrip(int channelIndex);
    ~MixerChannelStrip();

    // Disable copy
    MixerChannelStrip(const MixerChannelStrip&) = delete;
    MixerChannelStrip& operator=(const MixerChannelStrip&) = delete;

    /// Channel identity
    int channelIndex() const { return channelIndex_; }
    int64_t instanceId() const { return instanceId_; }

    /// --- Control surface (thread-safe via atomics for simple values) ---

    /// Volume in dB (-inf to +12.0)
    float volume() const { return volume_; }
    void setVolume(float db);

    /// Pan: -1.0 (full left) to +1.0 (full right). 0.0 = center.
    float pan() const { return pan_; }
    void setPan(float pan);

    /// Mute
    bool mute() const { return mute_; }
    void setMute(bool mute);

    /// Solo — overrides mute for monitoring
    bool solo() const { return solo_; }
    void setSolo(bool solo);

    /// Channel type for UI classification
    MixerChannelType channelType() const { return channelType_; }
    void setChannelType(MixerChannelType type) { channelType_ = type; }

    /// User-assignable label
    const std::string& label() const { return label_; }
    void setLabel(const std::string& label) { label_ = label; }

    /// --- Input processing ---

    /// High-pass filter
    bool hpEnabled() const { return hpEnabled_; }
    void setHpEnabled(bool enabled) { hpEnabled_ = enabled; }
    float hpFrequency() const { return hpFrequency_; }
    void setHpFrequency(float freq) { hpFrequency_ = freq; }

    /// --- Aux Sends ---

    void setAuxSend(int index, const AuxSendConfig& config);
    const AuxSendConfig& auxSend(int index) const;
    size_t auxSendCount() const { return auxSends_.size(); }
    void resizeAuxSends(size_t count);

    /// --- Audio Processing (real-time thread) ---

    /// Set sample rate and max buffer size
    void setSampleRate(uint32_t sampleRate);
    void setMaxBufferSize(size_t frames);

    /// Allocate internal processing buffers. Must be called before process().
    void allocateBuffers();

    /// Process one audio block through this channel strip.
    /// Reads from input, runs HPF, applies volume/pan.
    /// Output goes to provided output buffer(s).
    void process(
        const float* const* inputBuffers,
        size_t inputChannels,
        float* const* outputBuffers,
        size_t outputChannels,
        uint32_t frames
    );

    /// Get post-FX, pre-fader audio for aux send calculation
    const float* postFxBuffer(int channel) const {
        if (channel < (int)postFxBuffers_.size()) return postFxBuffers_[channel].data();
        return nullptr;
    }

    /// Get pre-FX audio for pre-fader aux sends
    const float* preFxBuffer(int channel) const {
        if (channel < (int)preFxBuffers_.size()) return preFxBuffers_[channel].data();
        return nullptr;
    }

    /// Calculate aux send level considering pre/post fader and mute
    float effectiveAuxLevel(int auxIndex, bool anySoloActive) const;

    /// VU meter values (peak, not RMS — computed during process)
    float vuLeft() const { return vuLeft_; }
    float vuRight() const { return vuRight_; }

    /// --- Lifecycle ---

    void Activate();
    void Deactivate();
    void Unprepare();

private:
    int channelIndex_;
    int64_t instanceId_;

    static std::atomic<int64_t> nextInstanceId_;

    // Control values (atomic for RT-safe reads from control thread)
    std::atomic<float> volume_{-96.0f};  // dB, -inf default
    std::atomic<float> pan_{0.0f};
    std::atomic<bool> mute_{false};
    std::atomic<bool> solo_{false};
    std::atomic<bool> hpEnabled_{false};
    std::atomic<float> hpFrequency_{80.0f};

    MixerChannelType channelType_ = MixerChannelType::Instrument;
    std::string label_;

    // Aux sends
    std::vector<AuxSendConfig> auxSends_;

    // Audio buffers (allocated at prepare time)
    std::vector<std::vector<float>> preFxBuffers_;   // Before FX chain (for pre-fader sends)
    std::vector<std::vector<float>> postFxBuffers_;  // After FX chain, before fader

    // Sample rate / buffer size
    uint32_t sampleRate_ = 48000;
    size_t maxBufferSize_ = 512;

    // VU tracking
    float vuLeft_ = -96.0f;
    float vuRight_ = -96.0f;

    // Simple 1-pole HPF state (per channel)
    struct HpfState {
        float x1 = 0.0f, y1 = 0.0f;
    };
    std::vector<HpfState> hpfStates_;

    // Apply pan law: constant power (-3dB center)
    void applyPan(float& leftGain, float& rightGain) const;

    // Apply HPF biquad to a buffer
    void applyHpf(float* buffer, uint32_t frames, HpfState& state);
};

} // namespace mixer
