#include "buttons.h"
#include "config.h"

struct BtnState {
    uint8_t  lastLevel;
    uint32_t lastChangeMs;
    bool     consumed;
};

static BtnState s_up   = {HIGH, 0, false};
static BtnState s_down = {HIGH, 0, false};
static BtnState s_ok   = {HIGH, 0, false};

static ButtonEvent checkBtn(BtnState& s, uint8_t pin, ButtonEvent ev) {
    uint8_t level = digitalRead(pin);
    uint32_t now  = millis();

    if (level != s.lastLevel) {
        s.lastLevel    = level;
        s.lastChangeMs = now;
        s.consumed     = false;
    }

    if (!s.consumed &&
        (now - s.lastChangeMs) >= BUTTON_DEBOUNCE_MS &&
        s.lastLevel == LOW) {
        s.consumed = true;
        return ev;
    }
    return ButtonEvent::NONE;
}

void buttons_init() {
    pinMode(PIN_BTN_UP,   INPUT_PULLUP);
    pinMode(PIN_BTN_DOWN, INPUT_PULLUP);
    pinMode(PIN_BTN_OK,   INPUT_PULLUP);
}

ButtonEvent buttons_update() {
    ButtonEvent ev;
    ev = checkBtn(s_up,   PIN_BTN_UP,   ButtonEvent::UP_PRESS);
    if (ev != ButtonEvent::NONE) return ev;
    ev = checkBtn(s_down, PIN_BTN_DOWN, ButtonEvent::DOWN_PRESS);
    if (ev != ButtonEvent::NONE) return ev;
    ev = checkBtn(s_ok,   PIN_BTN_OK,   ButtonEvent::OK_PRESS);
    return ev;
}

bool buttons_check_ok_held_at_boot() {
    if (digitalRead(PIN_BTN_OK) != LOW) return false;
    uint32_t start = millis();
    while (millis() - start < BOOT_HOLD_MS) {
        if (digitalRead(PIN_BTN_OK) != LOW) return false;
        delay(10);
    }
    return true;
}
