/*
 * SISTEMA NAVAL PRO - 6 PINES INDEPENDIENTES
 * Cada sensor tiene su propio Pin físico. 
 * Sin direcciones MAC, sin confusiones.
 * 
 * Formato de envío: temperatura,id_zona,fecha_hora,api_key
 */

#include <WiFi.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h> 
#include <OneWire.h>
#include <DallasTemperature.h>
#include <time.h>

// ==========================================
// 1. CONFIGURACIÓN RED Y SERVIDOR
// ==========================================
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* serverURL = "https://www.devmastering.com/webservices/buque2/api/buque.php";
const char* apiKey = "BUQUE2024_SECRET_KEY_XYZ789";

// ==========================================
// 2. CONFIGURACIÓN NTP (Para fecha y hora)
// ==========================================
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = -3 * 3600;  // GMT-3 (Argentina)
const int daylightOffset_sec = 0;      // Sin horario de verano

// ==========================================
// 3. CONFIGURACIÓN DE ZONAS Y PINES
// ==========================================

// Definimos cuántos sensores usaremos
const int CANTIDAD_SENSORES = 6;

// LISTA DE PINES FÍSICOS (Donde conectas el cable verde de cada uno)
const int PINES[CANTIDAD_SENSORES] = { 4, 13, 14, 18, 19, 21 };

// NOMBRES PARA MOSTRAR EN PANTALLA
String NOMBRES[CANTIDAD_SENSORES] = {
  "Sala de Maquinas",   // Pin 4
  "Bodega de Carga",    // Pin 13
  "Puente de Mando",    // Pin 14
  "Camarote Capitan",   // Pin 18
  "Comedor Tripulacion",// Pin 19
  "Exterior Cubierta"   // Pin 21
};

// IDs PARA LA BASE DE DATOS (Se envían en el campo id_zona)
int IDS_WEB[CANTIDAD_SENSORES] = { 1, 2, 3, 4, 5, 6 };


// ==========================================
// 4. GESTIÓN DE OBJETOS (MAGIA DE POINTERS)
// ==========================================
// Creamos arrays de objetos para manejarlos en bucle
OneWire* cables[CANTIDAD_SENSORES];
DallasTemperature* sensores[CANTIDAD_SENSORES];

void setup() {
  Serial.begin(115200);
  
  Serial.println("------------------------------------");
  Serial.println("⚓ INICIANDO SISTEMA POR PINES INDIVIDUALES");
  
  // Inicializamos cada pin por separado
  for(int i=0; i < CANTIDAD_SENSORES; i++) {
    // Crear la instancia OneWire para el pin específico
    cables[i] = new OneWire(PINES[i]);
    
    // Crear la instancia DallasTemp asociada a ese cable
    sensores[i] = new DallasTemperature(cables[i]);
    
    // Iniciar el sensor
    sensores[i]->begin();
    
    Serial.print("🔹 Configurado ");
    Serial.print(NOMBRES[i]);
    Serial.print(" en PIN ");
    Serial.println(PINES[i]);
  }
  Serial.println("------------------------------------");

  // Conectar WiFi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Conectando a WiFi");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n✅ WiFi Conectado!");
  Serial.print("IP asignada: ");
  Serial.println(WiFi.localIP());

  // Configurar NTP para obtener fecha y hora
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.println("⏰ Configurando hora NTP...");
  
  // Esperar a que se sincronice la hora (máximo 10 segundos)
  int intentos = 0;
  while (time(nullptr) < 1000000000 && intentos < 20) {
    delay(500);
    intentos++;
    Serial.print(".");
  }
  Serial.println();
  
  if (time(nullptr) > 1000000000) {
    Serial.println("✅ Hora sincronizada correctamente");
    struct tm timeinfo;
    if (getLocalTime(&timeinfo)) {
      Serial.print("📅 Fecha/Hora actual: ");
      Serial.println(&timeinfo, "%Y-%m-%d %H:%M:%S");
    }
  } else {
    Serial.println("⚠️ No se pudo sincronizar la hora. Se usará hora del servidor.");
  }
}

void loop() {
  if(WiFi.status() == WL_CONNECTED){
    
    Serial.println("\n📡 INICIANDO RONDA DE LECTURAS...");

    // Recorremos los 6 sensores uno por uno
    for(int i=0; i < CANTIDAD_SENSORES; i++) {
      
      // 1. Pedir temperatura al sensor específico "i"
      sensores[i]->requestTemperatures();
      float temp = sensores[i]->getTempCByIndex(0);

      // 2. Verificar si está conectado
      // -127 significa que el cable está cortado o falta la resistencia
      if(temp > -100) {
        Serial.print("➡️ [" + NOMBRES[i] + "] (Pin " + String(PINES[i]) + "): ");
        Serial.print(temp);
        Serial.println("°C");
        
        // 3. Enviar al servidor
        enviarAlServidor(temp, IDS_WEB[i]);
        
        delay(2000); // Pausa suave entre sensores
      } else {
        Serial.print("❌ ERROR en " + NOMBRES[i] + " (Pin " + String(PINES[i]) + ")");
        Serial.println(" -> Revisa conexión o resistencia.");
      }
    }
    
    Serial.println("💤 Ronda terminada. Esperando...");

  } else {
    Serial.println("⚠️ WiFi desconectado");
    // Intentar reconectar
    WiFi.begin(ssid, password);
  }

  delay(10000); // Esperar 10 segundos antes de la siguiente ronda
}

// Función de envío con fecha y hora
void enviarAlServidor(float temperatura, int idZona) {
  // Obtener fecha y hora actual
  struct tm timeinfo;
  String fechaHora = "";
  
  if (getLocalTime(&timeinfo)) {
    // Formatear fecha y hora: YYYY-MM-DD HH:MM:SS
    char buffer[20];
    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &timeinfo);
    fechaHora = String(buffer);
  } else {
    // Si no hay hora sincronizada, usar timestamp Unix
    // El servidor lo rechazará pero al menos intentamos
    fechaHora = String(time(nullptr));
    Serial.println("   ⚠️ Usando timestamp Unix (hora no sincronizada)");
  }
  
  // Formato: temperatura,id_zona,fecha_hora,api_key
  String mensaje = String(temperatura, 2) + "," + 
                   String(idZona) + "," + 
                   fechaHora + "," + 
                   String(apiKey);

  Serial.print("   📤 Enviando: ");
  Serial.println(mensaje);

  WiFiClientSecure client;
  client.setInsecure(); // Ignorar certificado SSL (solo para desarrollo)
  HTTPClient http;
  
  if (http.begin(client, serverURL)) {
      http.addHeader("Content-Type", "text/plain"); 
      int code = http.POST(mensaje);
      
      if(code > 0) {
         String respuesta = http.getString();
         Serial.print("   ✅ Respuesta servidor (");
         Serial.print(code);
         Serial.print("): ");
         Serial.println(respuesta);
      } else {
         Serial.print("   ❌ Error Servidor: ");
         Serial.println(code);
         Serial.print("   Error: ");
         Serial.println(http.errorToString(code));
      }
      http.end();
  } else {
    Serial.println("   ❌ Error: No se pudo conectar al servidor");
  }
}

