<?php
/**
 * NEXUS IT - Cron: Verificar Alertas
 * Ejecutar cada 15 minutos via cPanel Cron Jobs
 * Comando: php /home/USUARIO/public_html/ana/cron/check_alerts.php
 */

require_once dirname(__DIR__) . '/api/config/app.php';
require_once dirname(__DIR__) . '/api/config/database.php';

$db = getDB();

echo "[" . date('Y-m-d H:i:s') . "] Verificando alertas...\n";

// Obtener umbrales de configuración
function getConfig(PDO $db, string $clave, $default = null) {
    $stmt = $db->prepare("SELECT valor FROM configuracion WHERE clave = ?");
    $stmt->execute([$clave]);
    return $stmt->fetchColumn() ?: $default;
}

$umbralDisco = (int)getConfig($db, 'agent_alerta_disco_pct', 90);
$umbralRam   = (int)getConfig($db, 'agent_alerta_ram_pct', 95);
$umbralTemp  = (int)getConfig($db, 'agent_alerta_temp_cpu', 85);
$umbralCpu   = 95; // CPU al 95%
$horasOffline = (int)getConfig($db, 'agent_alerta_offline_horas', 24);

$alertasCreadas = 0;

// 1. Verificar telemetría reciente de cada activo
$stmt = $db->query("
    SELECT t.activo_id, t.cpu_uso_pct, t.ram_uso_pct, t.disco_uso_pct, t.temp_cpu,
        a.codigo_activo, a.hostname
    FROM telemetria t
    INNER JOIN (
        SELECT activo_id, MAX(id) AS max_id FROM telemetria GROUP BY activo_id
    ) latest ON t.id = latest.max_id
    INNER JOIN activos a ON t.activo_id = a.id
    WHERE a.estado = 'activo'
");

$stmtCheck = $db->prepare("
    SELECT COUNT(*) FROM alertas 
    WHERE activo_id = ? AND tipo_alerta = ? AND resuelta = 0
");

$stmtInsert = $db->prepare("
    INSERT INTO alertas (activo_id, tipo_alerta, mensaje, severidad)
    VALUES (?, ?, ?, ?)
");

while ($row = $stmt->fetch()) {
    $equipo = $row['codigo_activo'] . ($row['hostname'] ? " ({$row['hostname']})" : '');
    
    // Disco lleno
    if ($row['disco_uso_pct'] !== null && $row['disco_uso_pct'] >= $umbralDisco) {
        $stmtCheck->execute([$row['activo_id'], 'disco_lleno']);
        if ($stmtCheck->fetchColumn() == 0) {
            $sev = $row['disco_uso_pct'] >= 95 ? 'critical' : 'warning';
            $stmtInsert->execute([$row['activo_id'], 'disco_lleno', "Disco al {$row['disco_uso_pct']}% en $equipo", $sev]);
            $alertasCreadas++;
        }
    }
    
    // RAM alta
    if ($row['ram_uso_pct'] !== null && $row['ram_uso_pct'] >= $umbralRam) {
        $stmtCheck->execute([$row['activo_id'], 'ram_alta']);
        if ($stmtCheck->fetchColumn() == 0) {
            $stmtInsert->execute([$row['activo_id'], 'ram_alta', "RAM al {$row['ram_uso_pct']}% en $equipo", 'warning']);
            $alertasCreadas++;
        }
    }
    
    // Temperatura CPU
    if ($row['temp_cpu'] !== null && $row['temp_cpu'] >= $umbralTemp) {
        $stmtCheck->execute([$row['activo_id'], 'temp_alta']);
        if ($stmtCheck->fetchColumn() == 0) {
            $sev = $row['temp_cpu'] >= 95 ? 'critical' : 'warning';
            $stmtInsert->execute([$row['activo_id'], 'temp_alta', "CPU a {$row['temp_cpu']}°C en $equipo", $sev]);
            $alertasCreadas++;
        }
    }
    
    // CPU alta sostenida
    if ($row['cpu_uso_pct'] !== null && $row['cpu_uso_pct'] >= $umbralCpu) {
        $stmtCheck->execute([$row['activo_id'], 'cpu_alta']);
        if ($stmtCheck->fetchColumn() == 0) {
            $stmtInsert->execute([$row['activo_id'], 'cpu_alta', "CPU al {$row['cpu_uso_pct']}% en $equipo", 'warning']);
            $alertasCreadas++;
        }
    }
}

// 2. Equipos offline (sin reportar)
$stmt = $db->prepare("
    SELECT id, codigo_activo, hostname, ultimo_reporte
    FROM activos 
    WHERE estado = 'activo' AND agent_token IS NOT NULL 
    AND ultimo_reporte < DATE_SUB(NOW(), INTERVAL ? HOUR)
");
$stmt->execute([$horasOffline]);

while ($row = $stmt->fetch()) {
    $stmtCheck->execute([$row['id'], 'offline']);
    if ($stmtCheck->fetchColumn() == 0) {
        $equipo = $row['codigo_activo'] . ($row['hostname'] ? " ({$row['hostname']})" : '');
        $stmtInsert->execute([$row['id'], 'offline', "Equipo offline hace más de {$horasOffline}h: $equipo", 'warning']);
        $alertasCreadas++;
    }
}

// 3. Garantías por vencer (próximos 30 días)
$stmt = $db->query("
    SELECT id, codigo_activo, hostname, garantia_hasta
    FROM activos
    WHERE estado = 'activo' AND garantia_hasta IS NOT NULL
    AND garantia_hasta BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY)
");

while ($row = $stmt->fetch()) {
    $stmtCheck->execute([$row['id'], 'garantia_vence']);
    if ($stmtCheck->fetchColumn() == 0) {
        $dias = (int)((strtotime($row['garantia_hasta']) - time()) / 86400);
        $equipo = $row['codigo_activo'] . ($row['hostname'] ? " ({$row['hostname']})" : '');
        $stmtInsert->execute([$row['id'], 'garantia_vence', "Garantía vence en {$dias} días: $equipo", 'info']);
        $alertasCreadas++;
    }
}

// 4. Auto-resolver alertas de telemetría que ya bajaron
$db->exec("
    UPDATE alertas al
    INNER JOIN (
        SELECT t.activo_id, t.cpu_uso_pct, t.ram_uso_pct, t.disco_uso_pct, t.temp_cpu
        FROM telemetria t
        INNER JOIN (SELECT activo_id, MAX(id) AS max_id FROM telemetria GROUP BY activo_id) latest ON t.id = latest.max_id
    ) tel ON al.activo_id = tel.activo_id
    SET al.resuelta = 1, al.resuelta_at = NOW()
    WHERE al.resuelta = 0
    AND (
        (al.tipo_alerta = 'disco_lleno' AND tel.disco_uso_pct < {$umbralDisco})
        OR (al.tipo_alerta = 'ram_alta' AND tel.ram_uso_pct < {$umbralRam})
        OR (al.tipo_alerta = 'temp_alta' AND tel.temp_cpu < {$umbralTemp})
        OR (al.tipo_alerta = 'cpu_alta' AND tel.cpu_uso_pct < {$umbralCpu})
    )
");

echo "Alertas creadas: $alertasCreadas\n";
echo "Proceso completado.\n";
