<?php
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/includes/functions.php';

// Verificação simples de segurança: apenas aceita requests internos ou com token
$token = $_GET['token'] ?? '';
$settingsToken = get_system_setting('cron_http_token', CRON_HTTP_TOKEN);

if ($token !== $settingsToken && $_SERVER['REMOTE_ADDR'] !== '127.0.0.1' && !isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    // Permite chamadas internas da rede Docker (geralmente IPs locais)
    $ip = $_SERVER['REMOTE_ADDR'];
    if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
        // É IP privado/docker, permite
    } else {
        http_response_code(403);
        exit('Acesso Negado.');
    }
}

$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if (!$id) {
    http_response_code(400);
    exit('ID invalido.');
}

$pdo = db();
$stmt = $pdo->prepare("SELECT * FROM monitored_ips WHERE id = ? LIMIT 1");
$stmt->execute([$id]);
$ip = $stmt->fetch();

if (!$ip || !$ip['active']) {
    exit('Inativo ou Nao Encontrado.');
}

// Verifica se já não foi checado recentemente (evita double-run)
if ($ip['last_check_at']) {
    $last = strtotime($ip['last_check_at']);
    $interval = (int)$ip['interval_seconds'];
    if (time() - $last < $interval - 2) {
        // Menos do que o intervalo, pula
        exit('Skipped (Too soon)');
    }
}

// 1. Faz o Ping
$result = ping_host($ip['host'], (int)$ip['timeout_ms'], $ip['check_method'] ?? 'auto');
$status = $result['status'];
$latency = $result['latency_ms'];
$now = new DateTimeImmutable('now');

// 2. Grava log
$stmtLog = $pdo->prepare("
    INSERT INTO ping_logs (monitored_ip_id, status, latency_ms, checked_at)
    VALUES (?, ?, ?, NOW())
");
$stmtLog->execute([$ip['id'], $status, $latency]);

// 3. Atualiza IP
$previousStatus = $ip['last_status'];
$stmtUpd = $pdo->prepare("
    UPDATE monitored_ips
    SET last_status = ?, last_latency_ms = ?, last_check_at = NOW()
    WHERE id = ?
");
$stmtUpd->execute([$status, $latency, $ip['id']]);

// 4. Processa alertas
$channels = get_alert_channels((int)$ip['id']);
if (!$channels && !empty($ip['alert_email'])) {
    if ($previousStatus !== 'unknown' && $previousStatus !== $status) {
        $subject = "[MonitorPing] " . $ip['label'] . " (" . $ip['host'] . ") está agora " . strtoupper($status);
        $message = "O host " . $ip['label'] . " (" . $ip['host'] . ") mudou de status para: " . $status .
                    "\nLatência: " . ($latency !== null ? $latency . " ms" : "N/A") .
                    "\nData/hora: " . date('Y-m-d H:i:s');
        @mail($ip['alert_email'], $subject, $message);

        $stmtAlert = $pdo->prepare("
            INSERT INTO alerts_sent (monitored_ip_id, channel_id, type, message, sent_at)
            VALUES (?, NULL, 'email', ?, NOW())
        ");
        $stmtAlert->execute([$ip['id'], $message]);
    }
    echo "OK (Basic Email)";
    exit;
}

foreach ($channels as $channel) {
    if (empty($channel['active'])) {
        continue;
    }
    $channelId = $channel['id'] ?? null;

    if ($status === 'online') {
        if ($channelId) {
            $pdo->prepare("UPDATE alert_channels SET consecutive_failures = 0 WHERE id = ?")->execute([$channelId]);
        }
        if ($previousStatus === 'offline') {
            $channel['consecutive_failures'] = 0;
            $channel['last_sent_at'] = $now->format('Y-m-d H:i:s');
            send_channel_alert($pdo, $channel, $ip, $status, $latency);
        }
        continue;
    }

    $newFailures = (int)($channel['consecutive_failures'] ?? 0) + 1;
    if ($channelId) {
        $pdo->prepare("UPDATE alert_channels SET consecutive_failures = ? WHERE id = ?")->execute([$newFailures, $channelId]);
    }

    if ($newFailures < max(1, (int)($channel['min_failures'] ?? 1))) {
        continue;
    }
    if (channel_in_cooldown($channel, $now)) {
        continue;
    }
    if (channel_in_silence_window($channel, $now)) {
        continue;
    }

    $channel['consecutive_failures'] = $newFailures;
    $channel['last_sent_at'] = $now->format('Y-m-d H:i:s');
    send_channel_alert($pdo, $channel, $ip, $status, $latency, $newFailures);
}

echo "OK (Channels Processed)";
