#include <Arduino.h>
#include "PirSensor.h"

// GPIO по умолчанию — см. WIRING.md.
constexpr uint8_t kPirPin = 13;
constexpr uint8_t kStatusLedPin = 2;   // Встроенный LED большинства ESP32 DevKit — индикатор "движение"
constexpr uint8_t kRelayPin = 4;       // Опционально: реле/нагрузка, см. WIRING.md

constexpr uint32_t kHoldTimeMs = 2000;
constexpr uint32_t kDebounceMs = 50;
constexpr uint32_t kWarmupMs = 5000;   // см. @note PirSensor::isWarmingUp в PirSensor.h
constexpr uint32_t kPrintPeriodMs = 500;

PirSensor pir(kPirPin, kHoldTimeMs, kDebounceMs);

void setup() {
    Serial.begin(115200);
    delay(250);

    pinMode(kStatusLedPin, OUTPUT);
    pinMode(kRelayPin, OUTPUT);
    digitalWrite(kStatusLedPin, LOW);
    digitalWrite(kRelayPin, LOW);

    Serial.println(F("\n=== [PIR_sensor_AM312] Motion Detection Test ==="));
    Serial.printf("Hold time %lu мс, debounce %lu мс\n", kHoldTimeMs, kDebounceMs);

    pir.begin();

    Serial.printf("Прогрев датчика ~%lu мс — возможны ложные срабатывания, см. THEORY.md.\n", kWarmupMs);
    Serial.println(F("Не блокирует loop() — статус печатается сразу, прогрев только помечен в логе."));
    Serial.println(F("------------------------------------"));
}

void loop() {
    pir.update();

    const PirSensor::Data& data = pir.getData();
    digitalWrite(kStatusLedPin, data.motionActive ? HIGH : LOW);
    digitalWrite(kRelayPin, data.motionActive ? HIGH : LOW);

    static bool wasActive = false;
    static uint32_t lastPrintMs = 0;
    uint32_t now = millis();

    // Печатаем сразу при смене статуса — для точного таймлайна событий в визуализаторе.
    bool changed = (data.motionActive != wasActive);
    if (changed || now - lastPrintMs >= kPrintPeriodMs) {
        lastPrintMs = now;
        wasActive = data.motionActive;
        const char* warm = pir.isWarmingUp(kWarmupMs) ? " прогрев" : "";
        if (data.motionActive) {
            Serial.printf("[MOTION] движение обнаружено%s\n", warm);
        } else {
            Serial.printf("[IDLE]   покой  предыдущее=%lu мс%s\n", data.lastMotionDurationMs, warm);
        }
    }
}
