<?php
/**
 * BUQUE.PHP - VERSIÓN DE ALTA ROBUSTEZ Y RENDIMIENTO
 */

// 1. CONFIGURACIÓN
$cacheDir = __DIR__ . '/../cache';
if (!is_dir($cacheDir)) @mkdir($cacheDir, 0755, true);

// 2. CARGAR CONFIGURACIÓN
require_once '../config.php';
header('Content-Type: application/json; charset=utf-8');

// 3. RECEPCIÓN DE DATOS
$rawData = file_get_contents('php://input');
if (empty($rawData)) {
    exit;
}

// 4. DETECTAR FORMATO Y LIMPIAR
$isJson = (substr(trim($rawData), 0, 1) === '{');
$consolidatedTemps = [];
$buqueId = 'BOUCINA-01'; // Default ASCII

if ($isJson) {
    $data = json_decode($rawData, true);
    if (!$data) {
        exit;
    }
    if (!isset($data['apiKey']) || $data['apiKey'] !== API_KEY) {
        exit;
    }
    $buqueId = $data['buqueId'] ?? $buqueId;
    $idZona = 15;
    $temperatura = $data['lastTemp'] ?? 0;
    $consolidatedTemps = $data['temps'] ?? [];
} elseif (strpos($rawData, '|') !== false) {
    // NUEVO FORMATO CONSOLIDADO: ID:TEMP|ID:TEMP|...|apikey:KEY
    // Registro detallado para auditoría
    $logData = "[" . date('Y-m-d H:i:s') . "] RAW: " . $rawData . " | IP: " . ($_SERVER['REMOTE_ADDR'] ?? '---') . "\n";
    @file_put_contents(__DIR__ . '/../cache/debug_payload.log', $logData, FILE_APPEND);

    $parts = explode('|', trim($rawData));
    $apiKey = '';
    foreach ($parts as $part) {
        if (strpos($part, ':') !== false) {
            $subParts = explode(':', $part, 2);
            $key = trim($subParts[0]);
            $val = trim($subParts[1]);
            
            if ($key === 'apikey') {
                $apiKey = $val;
            } elseif (is_numeric($key)) {
                $consolidatedTemps[(int)$key] = (float)$val;
            } elseif ($key === 'buqueId') {
                $buqueId = $val;
            }
        }
    }
    
    if ($apiKey !== API_KEY) {
        exit;
    }
    
    $idZona = 999; // FORZAR SINCRONIZACIÓN INMEDIATA PARA FORMATO CONSOLIDADO
} else {
    $values = array_map('trim', explode(',', trim($rawData)));
    if (count($values) < 4) {
        exit;
    }
    $temperatura = $values[0];
    $idZona = (int) $values[1];
    $apiKey = $values[3] ?? '';
    $buqueIdFromPayload = $values[4] ?? null;
    
    if ($apiKey !== API_KEY) {
        exit;
    }
    
    if (!empty($buqueIdFromPayload)) {
        $buqueId = $buqueIdFromPayload;
    }
}

// 5. MANEJO DE CACHÉ

// 5. MANEJO DE CACHÉ
$safeBuqueId = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $buqueId);
$cacheFile = $cacheDir . "/ship_$safeBuqueId.json"; 
$now = time();
$syncInterval = 120; // 2 minutos

$cacheData = null;
if (file_exists($cacheFile)) {
    $fp = fopen($cacheFile, 'c+');
    if ($fp && flock($fp, LOCK_SH)) { // Bloqueo compartido para lectura
        $content = stream_get_contents($fp);
        if (!empty($content)) {
            $decoded = json_decode($content, true);
            if (is_array($decoded)) {
                $cacheData = $decoded;
            }
        }
        flock($fp, LOCK_UN);
    }
    if ($fp) fclose($fp);
}

// INICIALIZACIÓN RESILIENTE: Si el archivo existe pero falló la lectura (concurrencia),
// NO RESETEAMOS a vacío. Simplemente inicializamos una estructura limpia si realmente no hay nada previo.
if (!is_array($cacheData)) {
    // Si llegamos aquí y el archivo existe, es probable que haya habido un error de concurrencia.
    // Pero si el archivo NO existe, sí inicializamos.
    $cacheData = [
        'temps' => array_fill(1, 16, null),
        'timestamps' => array_fill(1, 16, 0),
        'last_db_sync' => 0,
        'buqueId' => $buqueId
    ];
}

// ACTUALIZAR CACHÉ (Solo los sensores que vienen en este paquete)
if (!empty($consolidatedTemps)) {
    foreach ($consolidatedTemps as $idx => $val) {
        $idx = (int)$idx;
        if ($idx >= 1 && $idx <= 16) {
            $cacheData['temps'][$idx] = $val;
            $cacheData['timestamps'][$idx] = $now;
        }
    }
} else {
    if ($idZona >= 1 && $idZona <= 16) {
        $cacheData['temps'][$idZona] = $temperatura;
        $cacheData['timestamps'][$idZona] = $now;
    }
}

$cacheData['last_contact'] = date('Y-m-d H:i:s');
$cacheData['ip'] = $_SERVER['REMOTE_ADDR'] ?? '---';

// 6. SINCRONIZACIÓN CON BASE DE DATOS
$lastSync = (int)($cacheData['last_db_sync'] ?? 0);
$isConsolidated = !empty($consolidatedTemps);
$shouldSyncDB = ($now - $lastSync >= $syncInterval) || ($idZona === 999) || $isConsolidated;

if ($shouldSyncDB) {
    try {
        $pdo = getDBConnection();
        if ($pdo) {
            $payload = [
                'unica' => true,
                'fecha' => $cacheData['last_contact'],
                'ip' => $cacheData['ip'],
                'sensor_timestamps' => $cacheData['timestamps']
            ];
            for ($i = 1; $i <= 16; $i++) {
                $payload["temp$i"] = $cacheData['temps'][$i];
            }

            $pdo->prepare("UPDATE ships SET last_contact = NOW(), last_payload = :p WHERE ship_id = :b")
                ->execute([':p' => json_encode($payload, JSON_UNESCAPED_UNICODE), ':b' => $buqueId]);

            if ($idZona !== 999 || $isConsolidated) {
                $cols = []; $vals = []; $params = [];
                $timeout = 600; // 10 minutos
                
                for ($i = 1; $i <= 16; $i++) {
                    $cols[] = "temp$i"; $vals[] = ":t$i";
                    $val = $cacheData['temps'][$i];
                    $ts = (int)($cacheData['timestamps'][$i] ?? 0);
                    
                    if ($ts > 0 && ($now - $ts) > $timeout) {
                        $val = null;
                        $cacheData['temps'][$i] = null;
                    }
                    $params[":t$i"] = ($val === null || $val === '') ? null : (float)$val;
                }
                $sql = "INSERT INTO mediciones (buque_id, " . implode(', ', $cols) . ", fecha, ip) VALUES (:b, " . implode(', ', $vals) . ", :f, :ip)";
                $params[':b'] = $buqueId;
                $params[':f'] = $cacheData['last_contact'];
                $params[':ip'] = $cacheData['ip'];
                $pdo->prepare($sql)->execute($params);
                $cacheData['last_db_sync'] = $now;
            }
        }
    } catch (Exception $e) {
        $logFile = __DIR__ . '/../logs/debug_buque.log';
        if (!is_dir(__DIR__ . '/../logs')) @mkdir(__DIR__ . '/../logs', 0755, true);
        @file_put_contents($logFile, "[" . date('Y-m-d H:i:s') . "] ERROR DB: " . $e->getMessage() . "\n", FILE_APPEND);
    }
}

// GUARDAR CACHÉ CON BLOQUEO EXCLUSIVO (Escritura Atómica)
$fp = fopen($cacheFile, 'c+');
if ($fp) {
    if (flock($fp, LOCK_EX)) {
        ftruncate($fp, 0);
        fwrite($fp, json_encode($cacheData, JSON_UNESCAPED_UNICODE));
        fflush($fp);
        flock($fp, LOCK_UN);
    }
    fclose($fp);
}

echo json_encode(["success" => true, "message" => "OK"]);
exit;