<?php
/**
 * ASISMA CRM - Vigilante de instancias de WhatsApp
 *
 * Revisa cada instancia activa en Evolution API: si la sesion esta caida
 * (close/connecting), intenta reconectarla automaticamente via restart +
 * connect (sin QR, usando las credenciales guardadas). Actualiza el estado
 * en whatsapp_instancias y deja bitacora en logs/vigilante_whatsapp.log.
 *
 * Pensado para correr cada 1 minuto como tarea programada de Windows.
 */
define('CRON_MODE', true);
$rootDir = dirname(dirname(__FILE__));
require $rootDir . '/config/config.php';

// Candado: evitar ejecuciones superpuestas
$candado = fopen(__FILE__, 'r');
if (!flock($candado, LOCK_EX | LOCK_NB)) exit(0);

$rutaLog = $rootDir . '/logs/vigilante_whatsapp.log';
function vigia_log($msg) {
    global $rutaLog;
    if (file_exists($rutaLog) && filesize($rutaLog) > 1048576) {
        @rename($rutaLog, $rutaLog . '.1');
    }
    @file_put_contents($rutaLog, '[' . date('Y-m-d H:i:s') . '] ' . $msg . PHP_EOL, FILE_APPEND);
}

function vigia_llamar($url, $metodo, $token, $payload = null) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $metodo);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_TIMEOUT, 25);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'apikey: ' . $token));
    if ($payload !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    $b = curl_exec($ch);
    $c = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return array($c, json_decode($b, true));
}

$db = Database::getInstance();
$instancias = $db->fetchAll("SELECT * FROM whatsapp_instancias WHERE activa = 1");

foreach ($instancias as $inst) {
    if (empty($inst['api_url']) || empty($inst['api_token'])) continue;
    $base = rtrim($inst['api_url'], '/');
    $nombre = rawurlencode($inst['nombre_instancia']);

    list($c, $r) = vigia_llamar("$base/instance/connectionState/$nombre", 'GET', $inst['api_token']);
    $estado = isset($r['instance']['state']) ? $r['instance']['state'] : ('http_' . $c);

    if ($estado === 'open') {
        if ($inst['estado'] !== 'conectada') {
            $db->update('whatsapp_instancias', array('estado' => 'conectada'), 'id = :id', array('id' => $inst['id']));
            vigia_log($inst['nombre_instancia'] . ': volvio a CONECTADA');
        }
        continue;
    }

    vigia_log($inst['nombre_instancia'] . ": caida (estado $estado), intentando reconectar...");
    if ($inst['estado'] !== 'desconectada') {
        $db->update('whatsapp_instancias', array('estado' => 'desconectada'), 'id = :id', array('id' => $inst['id']));
    }

    // Intento de reconexion sin QR: restart y luego connect
    vigia_llamar("$base/instance/restart/$nombre", 'POST', $inst['api_token']);
    sleep(5);
    vigia_llamar("$base/instance/connect/$nombre", 'GET', $inst['api_token']);
    sleep(8);

    list($c, $r) = vigia_llamar("$base/instance/connectionState/$nombre", 'GET', $inst['api_token']);
    $estadoFinal = isset($r['instance']['state']) ? $r['instance']['state'] : ('http_' . $c);
    if ($estadoFinal === 'open') {
        $db->update('whatsapp_instancias', array('estado' => 'conectada'), 'id = :id', array('id' => $inst['id']));
        vigia_log($inst['nombre_instancia'] . ': RECONECTADA automaticamente');
    } else {
        vigia_log($inst['nombre_instancia'] . ": sigue caida ($estadoFinal) — probablemente necesita escanear el QR");
    }
}

flock($candado, LOCK_UN);
