#include <ESP8266WiFi.h>
#include <ESP_Mail_Client.h>
#include <SPI.h>
#include "MFRC522.h"
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
WiFiClient clientTCP;

#define RST_PIN  D0 // GPIO5 
#define SS_PIN  D8 //  GPIO4 
MFRC522 mfrc522(SS_PIN, RST_PIN);
  byte liste_ID[3][4] =
  {
    {0xC1, 0x84, 0xB4, 0x01},
    {0x91, 0x9C, 0x91, 0x2B},
    {0xC1, 0x7D, 0xDF, 0xC7},
  };
int nombre_ID= sizeof(liste_ID)/sizeof(liste_ID [0]);
int acces=0;
int badge=-1;

int envoi=0;
#define ssid "SSID"
#define mot_de_passe "mot_de_passe"

const String ip_controleur="192.168.1.123";
const int port=8080;
String utilisateur="utilisateur";
String mdp_domoticz="mdp_domoticz";

const int id_interrupteur=2;

SMTPSession smtp;
SMTP_Message message;

void setup(){
  Serial.begin(74880);
  connexion_reseau();
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522
  ESP_Mail_Session session;
    /* Configuration du serveur NTP qui pemret de récupérer l'heure réelle ( */
    //session.time.ntp_server = "europe.pool.ntp.org,time.nist.gov,fr.pool.ntp.org,time4.google.com";
    //session.time.gmt_offset = 1;
    //session.time.day_light_offset = 1;
    /* Définition des entêtes de l'email (Nom, mail de l'expéditeur , sujet et email du destinaire */
    message.sender.name = "ESN";// Accent non possible sinon mauvais encodage
    message.sender.email = "email de l'expéditeur";
    message.subject = "Sujet de l'email";
    message.addRecipient(F("Nom Prénom du destinaire"), "email du destinataire");
    //
    //message.addRecipient("Nom Prénom du deuxième destinaire", "Mail du deuxième destinataire"); /: Ajout d'un autre email
    //message.addCc("Mail d'un destinaire en copie (cc)");// Ajout d'un email en copie
    //message.addBcc("Mail d'un destinaire en copie cachée (bcc)");// Ajout d'un destinataire en copie cachée

    //Send raw text message
    String textMsg = "Bonjour, \rvoici un email envoyé par l'ESP8266. \rBonne journée";
    message.text.content = textMsg.c_str();
    message.text.charSet = "UTF-8";
    message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64;//enc_7bit;
    //Possibilité de communiquer un niveau de priorité
    //* esp_mail_smtp_priority_high esp_mail_smtp_priority_normal esp_mail_smtp_priority_low 
    //message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;
}


void connexion_reseau(){
  delay(10);  
  Serial.print("Tentative de connexion: "); 
  Serial.println(ssid); 
  WiFi.begin(ssid, mot_de_passe);  
  while (WiFi.status() != WL_CONNECTED) { 
    delay(500); 
    Serial.print("."); 
  } 
  Serial.println("Connexion au réseau Wi-Fi réalisée"); 
  Serial.println("L'adresse IP est: "); 
  Serial.println(WiFi.localIP());
}

void loop(){
if ( ! mfrc522.PICC_IsNewCardPresent())
    return;
  // Verify if the NUID has been readed
  if ( ! mfrc522.PICC_ReadCardSerial())
    return;

  Serial.print("UID tag :");
  for (byte i = 0; i < mfrc522.uid.size; i++){
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
  }
  Serial.println();
  acces=0;
  badge=-1;
  for (int i = 0; i < nombre_ID; i++) {
    if (memcmp(mfrc522.uid.uidByte, liste_ID[i], 4) == 0){
      acces=1;
      badge=i+1;
    }
  }
  if (acces==1){
      Serial.print("Accès accordé au badge n°");
      Serial.println(badge);
      if (badge==1){
        ESP_Mail_Session session;
        MailClient.networkReconnect(true);
         
         /* Définition des paramètres du serveur SMTP (adresse, port, identifiant (souvent l'email) et mot de passe - dans certains cas, il est nécessiare de renseigner le domaine de l'utilisateur - à laisser vide sinon)*/
        session.server.host_name = "Nom d'hôte du serveur SMTP";
        session.server.port = 587;
        session.login.email = "Login pour le serveur SMTP";
        session.login.password = "Mot de passe pour le serveur SMTP";
        session.login.user_domain = "";
        /* Connexion au serveur avec la session configurée */
        if (!smtp.connect(&session))
          return;
      
        /* Envoi de l'email et fermeture de session */
        if (!MailClient.sendMail(&smtp, &message)){
          Serial.println("Erreur lors de l'envoi du message, " + smtp.errorReason());  
        }else{
          Serial.println("Mail envoyé");
          envoi=1;  
        }
      }
      if (badge==2){
          envoi_controleur_interrupteur(id_interrupteur, "On");
      }
  }else{
    Serial.println("Accès refusé");
  }
  // Halt PICC
  mfrc522.PICC_HaltA();
  // Stop encryption on PCD
  mfrc522.PCD_StopCrypto1();
}

void envoi_vers_controleur(int id, String nvalue, String svalue){
    HTTPClient http;
    String connexion_domoticz="";
    if (utilisateur!="" && mdp_domoticz!=""){
      connexion_domoticz=utilisateur+":"+mdp_domoticz+"@";//"+utilisateur+":"+mdp_domoticz+"@"
    }else{
      connexion_domoticz="";
    }
    if (nvalue!="" && svalue!=""){
      http.begin(clientTCP,"http://"+connexion_domoticz+ip_controleur+":"+port+"/json.htm?type=command&param=udevice&idx="+String(id)+"&nvalue="+nvalue+"&svalue="+svalue);
    }else if(nvalue==""){
      http.begin(clientTCP,"http://"+connexion_domoticz+ip_controleur+":"+port+"/json.htm?type=command&param=udevice&idx="+String(id)+"&svalue="+svalue);
    }else{
      http.begin(clientTCP,"http://"+connexion_domoticz+ip_controleur+":"+port+"/json.htm?type=command&param=udevice&idx="+String(id)+"&nvalue="+nvalue);
    }
    int httpCode =http.GET();
    if (httpCode > 0){
      String reponse = http.getString();   
      Serial.println(reponse); 
    }else{
      Serial.println(millis());
    } 
    http.end();   //Close connection  
}
void envoi_controleur_interrupteur(int id, String etat){
  String connexion_domoticz="";
  HTTPClient http;
  if (utilisateur!="" && mdp_domoticz!=""){
    connexion_domoticz=utilisateur+":"+mdp_domoticz+"@";//"+utilisateur+":"+mdp_domoticz+"@"
  }else{
    connexion_domoticz="";
  }    
  http.begin(clientTCP,"http://"+connexion_domoticz+ip_controleur+":"+port+"/json.htm?type=command&param=switchlight&idx="+String(id)+"&switchcmd="+etat);
  int httpCode =http.GET();
  if (httpCode > 0){
    String reponse = http.getString();   
    Serial.println(reponse); 
  } 
    http.end();
}
