#ifndef FASTLED_INTERNAL
#define FASTLED_INTERNAL
#endif
    
#include "fl/system/fastled.h"

#include "fl/system/fastpin.h"
#include "fl/stl/strstream.h"
#include "fl/log/log.h"
#include "fl/stl/assert.h"
#include "fl/sensors/pir.h"

namespace fl {

namespace {
int g_counter = 0;
string getButtonName(const char *button_name) {
    if (button_name) {
        return string(button_name);
    }
    int count = g_counter++;
    if (count == 0) {
        return string("PIR");
    }
    sstream s;
    s << "PirLowLevel " << g_counter++;
    return s.str();
}
} // namespace

PirLowLevel::PirLowLevel(int pin): mPin(pin) {
    mPin.setPinMode(DigitalPin::kInput);
}

bool PirLowLevel::detect() {
    return mPin.high();
}


Pir::Pir(int pin, u32 latchMs, u32 risingTime,
                         u32 fallingTime, const char* button_name)
    : mPir(pin), mRamp(risingTime, latchMs, fallingTime), mButton(getButtonName(button_name).c_str()) {
    mButton.onChanged([this](UIButton&) {
        this->mRamp.trigger(fl::millis());
    });
}

bool Pir::detect(u32 now) {
    bool currentState = mPir.detect();
    if (currentState && !mLastState) {
        // Use smart retrigger to avoid resetting brightness when already active
        mRamp.trigger(now);
    }
    mLastState = currentState;
    return mRamp.isActive(now);
}

u8 Pir::transition(u32 now) {
    // ensure detect() logic runs so we trigger on edges
    detect(now);
    return mRamp.update8(now);
}

} // namespace fl
