#include "PubSubClient.h"
#include <WiFi.h>
#include <ESP_Mail_Client.h>
 
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
 
#define SMTP_HOST "smtp.office365.com"
#define SMTP_PORT 587
int ledPinpir = 19;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;  
/* The sign in credentials */
#define AUTHOR_EMAIL "[email protected]"
#define AUTHOR_PASSWORD "phuong781"

/* Recipient's email*/
#define RECIPIENT_EMAIL "[email protected]"
/* The SMTP Session object used for Email sending */
SMTPSession smtp;
 
/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);



const char * MQTTServer = "broker.emqx.io";
const char * MQTT_Topic = "vlute/phanvanphuong2/led";

// Tạo ID ngẫu nhiên tại: https://www.guidgen.com/
const char * MQTT_ID = "vlute-iot-04";
int Port = 1883;

WiFiClient espClient;
PubSubClient client(espClient);
const int ledPin = 2;

void WIFIConnect() {
  Serial.println("Connecting to SSID: Wokwi-GUEST");
  WiFi.begin("Wokwi-GUEST", "");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected");
  Serial.print(", IP address: ");
  Serial.println(WiFi.localIP());
}

void MQTT_Reconnect() {
  while (!client.connected()) {
    if (client.connect(MQTT_ID)) {
      Serial.print("MQTT Topic: ");
      Serial.print(MQTT_Topic);
      Serial.print(" connected");
      client.subscribe(MQTT_Topic);
      Serial.println("");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}

void callback(char* topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.println(topic);
  Serial.print("Message: ");
  String stMessage;

  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    stMessage += (char)message[i];
  }
  Serial.println();
  if (stMessage == "on") {
    digitalWrite(ledPin, HIGH);
  }
  else if (stMessage == "off") {
    digitalWrite(ledPin, LOW);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(ledPinpir, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);  
  //mẫu
  /*   WIFIConnect();
  client.setServer(MQTTServer, Port);
  client.setCallback(callback);
  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  pinMode(ledPin, OUTPUT);

    smtp.debug(1);
 
  // Set the callback function to get the sending results 
  smtp.callback(smtpCallback);
 
  // Declare the session config data 
  ESP_Mail_Session session;
 
  // Set the session config 
  session.server.host_name = SMTP_HOST;
  session.server.port = SMTP_PORT;
  session.login.email = AUTHOR_EMAIL;
  session.login.password = AUTHOR_PASSWORD;
  session.login.user_domain = "";
 
  // Declare the message class 
  SMTP_Message message;
 
  // Set the message headers 
 
  message.sender.name = "THÔNG BÁO";
  message.sender.email = AUTHOR_EMAIL;
  message.subject = "ESP Test Email";
  message.addRecipient("CÓ LỬA", RECIPIENT_EMAIL);
 
 String htmlMsg = "<div style=\"color:#2f4468;\"><h1>CÓ LỬA</h1><p>Sent from ESP board</p></div>"; 
  String htmlMsg2 = "0";
  message.html.content = htmlMsg.c_str();
  message.text.charSet = "us-ascii";
  message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
  
  if (!smtp.connect(&session))
    return;
  if (!MailClient.sendMail(&smtp, &message))
    Serial.println("Error sending Email, " + smtp.errorReason());  */
 
}



void loop() {
   val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPinpir, HIGH);  // turn LED ON
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!");
      // We only want to print on the output change, not state
       WIFIConnect();
  client.setServer(MQTTServer, Port);
  client.setCallback(callback);
  pinMode(ledPin, OUTPUT);

    smtp.debug(1);
 
  /* Set the callback function to get the sending results */
  smtp.callback(smtpCallback);
 
  /* Declare the session config data */
  ESP_Mail_Session session;
 
  /* Set the session config */
  session.server.host_name = SMTP_HOST;
  session.server.port = SMTP_PORT;
  session.login.email = AUTHOR_EMAIL;
  session.login.password = AUTHOR_PASSWORD;
  session.login.user_domain = "";
 
  /* Declare the message class */
  SMTP_Message message;
 
  /* Set the message headers */
 
  message.sender.name = "CẢNH BÁO";
  message.sender.email = AUTHOR_EMAIL;
  message.subject = "ESP Test Email";
  message.addRecipient("CÓ LỬA", RECIPIENT_EMAIL);
 
  String htmlMsg = "<div style=\"color:#2f4468;\"><h1>CÓ LỬA</h1><p>Sent from ESP board</p></div>"; 
  //String htmlMsg = "0";
  message.html.content = htmlMsg.c_str();
  message.text.charSet = "us-ascii";
  message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
  
  if (!smtp.connect(&session))
    return;
  if (!MailClient.sendMail(&smtp, &message))
    Serial.println("Error sending Email, " + smtp.errorReason());
      pirState = HIGH;
    }
  } else {
    digitalWrite(ledPinpir, LOW); // turn LED OFF
    if (pirState == HIGH) {
      // we have just turned of
      Serial.println("Motion ended!");
      // We only want to print on the output change, not state
      pirState = LOW;
    }
  }
  delay(1000);
  if (!client.connected()) {
    MQTT_Reconnect();
  }
  client.loop();
  
}

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status){
  /* Print the current status */
  Serial.println(status.info());
 
  /* Print the sending result */
  if (status.success()){
    Serial.println("----------------");
    ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
    ESP_MAIL_PRINTF("Message sent failled: %d\n", status.failedCount());
    Serial.println("----------------\n");
    struct tm dt;
 
    for (size_t i = 0; i < smtp.sendingResult.size(); i++){
      /* Get the result item */
      SMTP_Result result = smtp.sendingResult.getItem(i);
      time_t ts = (time_t)result.timestamp;
      localtime_r(&ts, &dt);
 
      ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
      ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");
      ESP_MAIL_PRINTF("Date/Time: %d/%d/%d %d:%d:%d\n", dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday, dt.tm_hour, dt.tm_min, dt.tm_sec);
      ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients);
      ESP_MAIL_PRINTF("Subject: %s\n", result.subject);
    }
    Serial.println("----------------\n");
  }
}