#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <time.h>

//=====================
// WiFi
//=====================

const char *ssid = "--------";
const char *password = "-------";

//=====================
// Twilio
//=====================

String accountSID = "ACc28bc5ee1636531b0b62178aacf49349";
String authToken = "923708c252e0a3527273132ae2de6e44";

String fromWhatsApp = "whatsapp:+14155238886";

String toWhatsApp = "whatsapp:+918746826539";

//=====================
// Ultrasonic
//=====================

#define TRIG_PIN D1
#define ECHO_PIN D2

#define DETECT_DISTANCE 50

unsigned long lastTrigger = 0;

int visitorCount = 0;

#define LED_PIN D5

int detectionCount = 0;
const int requiredDetections = 3;

//=====================
// Distance
//=====================

long getDistance()
{

    digitalWrite(TRIG_PIN, LOW);
    delayMicroseconds(2);

    digitalWrite(TRIG_PIN, HIGH);
    delayMicroseconds(10);

    digitalWrite(TRIG_PIN, LOW);

    long duration =
        pulseIn(ECHO_PIN, HIGH, 30000);

    if (duration == 0)
        return 999;

    return duration * 0.034 / 2;
}

String getDateTime()
{

    time_t now = time(nullptr);

    struct tm *t = localtime(&now);

    char buffer[30];

    sprintf(buffer,
            "%02d-%02d-%04d %02d:%02d:%02d",
            t->tm_mday,
            t->tm_mon + 1,
            t->tm_year + 1900,
            t->tm_hour,
            t->tm_min,
            t->tm_sec);

    return String(buffer);
}

void sendWhatsApp(int count)
{

    BearSSL::WiFiClientSecure client;
    client.setInsecure();

    HTTPClient http;

    String url =
        "https://api.twilio.com/2010-04-01/Accounts/" + accountSID + "/Messages.json";

    http.begin(client, url);

    http.setAuthorization(
        accountSID.c_str(),
        authToken.c_str());

    http.addHeader(
        "Content-Type",
        "application/x-www-form-urlencoded");

    String message =
        "🚨 SECURITY ALERT 🚨\n\n"
        "⚠ Intruder Detected\n"
        "👤 Visitor Count: " +
        String(count) + "\n"
                        "📏 Trigger Distance: " +
        String(getDistance()) + " cm\n"
                                "🕒 Time: " +
        getDateTime() + "\n"
                        "📍 Location: Main Entrance\n\n"
                        "Powered by IoTrix";

    message.replace(" ", "%20");
    message.replace("\n", "%0A");

    String body =
        "From=whatsapp%3A%2B14155238886"
        "&To=whatsapp%3A%2B910000000000"
        "&Body=" +
        message;

    int response = http.POST(body);

    Serial.print("HTTP Response = ");
    Serial.println(response);

    String result = http.getString();

    Serial.println(result);

    http.end();
}

//=====================
// Setup
//=====================

void setup()
{

    Serial.begin(115200);

    pinMode(TRIG_PIN, OUTPUT);
    pinMode(ECHO_PIN, INPUT);
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, LOW);

    WiFi.begin(ssid, password);

    Serial.print("Connecting");

    while (WiFi.status() != WL_CONNECTED)
    {

        delay(500);
        Serial.print(".");
    }

    Serial.println();
    Serial.println("WiFi Connected");
    configTime(19800, 0, "pool.ntp.org", "time.nist.gov"); // India Time UTC+5:30
    delay(2000);
    Serial.println(WiFi.localIP());
    Serial.println(toWhatsApp);
    sendWhatsApp(1);
}

//=====================
// Loop
//=====================

void loop()
{

    long distance =
        getDistance();

    Serial.print("Distance: ");
    Serial.println(distance);

    if (distance > 0 && distance <= DETECT_DISTANCE && millis() - lastTrigger > 10000)
    {

        lastTrigger = millis();

        visitorCount++;

        Serial.println("Person Detected");

        // Blink LED 5 times
        for (int i = 0; i < 5; i++)
        {

            digitalWrite(LED_PIN, HIGH);
            delay(150);

            digitalWrite(LED_PIN, LOW);
            delay(150);
        }

        sendWhatsApp(visitorCount);
    }

    delay(500);
}
