<?php
declare(strict_types=1);

error_reporting(0);
ini_set('display_errors', '0');

require_once __DIR__ . '/db.php';
require_once __DIR__ . '/Cloudflare.php';
require_once __DIR__ . '/Telegram.php';

// بررسی امنیت دسترسی
$isCli = (php_sapi_name() === 'cli');
$isAuthorizedWeb = isset($_GET['key']) && defined('CRON_SECRET_KEY') && ($_GET['key'] === CRON_SECRET_KEY);

if (!$isCli && !$isAuthorizedWeb) {
    http_response_code(403);
    exit('Access Denied: 403 Forbidden');
}

function isNodeAlive(string $ip, int $port = 443, int $timeout = 3): bool {
    $fp = @fsockopen($ip, $port, $errno, $errstr, $timeout);
    if (is_resource($fp)) {
        fclose($fp);
        return true;
    }
    return false;
}

// واکشی کامل نودها
$stmt = $pdo->query("
    SELECT 
        n.*, 
        ca.name AS cf_account_name, 
        ca.api_token AS cf_api_token, 
        p.name AS panel_name, 
        p.panel_type,
        COALESCE(g.name, 'عمومی') AS resolved_group_name
    FROM nodes n
    JOIN cloudflare_accounts ca ON n.cf_account_id = ca.id
    JOIN panels p ON n.panel_id = p.id
    LEFT JOIN panel_groups g ON n.group_id = g.id
");
$nodes = $stmt->fetchAll();

if (empty($nodes)) {
    exit;
}

foreach ($nodes as $node) {
    $port = !empty($node['check_port']) ? (int)$node['check_port'] : 443;
    $country = !empty($node['country']) ? $node['country'] : 'نامشخص';
    $isOnline = isNodeAlive($node['main_ip'], $port);

    if ($node['status'] === 'manual_override') {
        continue;
    }

    // =======================================================
    // ۱. نود قطع است -> انتخاب زاپاس به صورت چرخشی (Round-Robin)
    // =======================================================
    if (!$isOnline && empty($node['assigned_backup_id'])) {
        // دریافت لیست تمام زاپاس‌های متعلق به این پنل
        $bStmt = $pdo->prepare("SELECT * FROM backup_nodes WHERE panel_id = ? ORDER BY id ASC");
        $bStmt->execute([$node['panel_id']]);
        $allBackups = $bStmt->fetchAll();

        if (!empty($allBackups)) {
            $totalBackups = count($allBackups);

            // محاسبه تعداد نودهای آفلاین فعلی این پنل برای چرخش عادلانه
            $cStmt = $pdo->prepare("SELECT COUNT(*) FROM nodes WHERE panel_id = ? AND assigned_backup_id IS NOT NULL");
            $cStmt->execute([$node['panel_id']]);
            $assignedCount = (int)$cStmt->fetchColumn();

            // انتخاب اندیس زاپاس با استفاده از باقیمانده تقسیم (Modulo)
            $backupIndex = $assignedCount % $totalBackups;
            $backup = $allBackups[$backupIndex];

            $cfError = '';
            $cfUpdated = Cloudflare::updateRecord(
                $node['cf_api_token'],
                $node['zone_id'],
                $node['record_id'],
                $node['domain_name'],
                $backup['ip'],
                (bool)$node['proxied'],
                $cfError
            );

            if ($cfUpdated) {
                $pdo->prepare("
                    UPDATE nodes 
                    SET current_ip = ?, status = 'offline', assigned_backup_id = ? 
                    WHERE id = ?
                ")->execute([$backup['ip'], $backup['id'], $node['id']]);

                $pType = strtoupper($node['panel_type']);
                $msg = "🔴 <b>هشدار: قطعی نود و سوییچ چرخشی به زاپاس</b>\n\n"
                     . "🏷 <b>نود:</b> {$node['name']}\n"
                     . "🌍 <b>کشور:</b> {$country}\n"
                     . "👥 <b>گروه:</b> {$node['resolved_group_name']}\n"
                     . "🏢 <b>پنل:</b> {$node['panel_name']} ({$pType})\n"
                     . "🌐 <b>ساب‌دامین:</b> <code>{$node['domain_name']}</code>\n"
                     . "❌ <b>آی‌پی قطع شده:</b> <code>{$node['main_ip']}</code>\n"
                     . "🔄 <b>آی‌پی زاپاس اختصاص داده شده:</b> <code>{$backup['ip']}</code> ({$backup['name']})\n"
                     . "⏱ <b>زمان:</b> " . date('Y-m-d H:i:s');
                Telegram::sendMessage($msg);
            }
        } else {
            $pType = strtoupper($node['panel_type']);
            $msg = "⚠️ <b>هشدار بحرانی: نود قطع است ولی هیچ زاپاسی برای این پنل ثبت نشده!</b>\n\n"
                 . "🏷 <b>نود:</b> {$node['name']}\n"
                 . "👥 <b>گروه:</b> {$node['resolved_group_name']}\n"
                 . "🏢 <b>پنل:</b> {$node['panel_name']} ({$pType})\n"
                 . "❌ <b>آی‌پی:</b> <code>{$node['main_ip']}</code>";
            Telegram::sendMessage($msg);
        }
    }

    // =======================================================
    // ۲. نود وصل شد -> بازگردانی به آی‌پی اصلی
    // =======================================================
    if ($isOnline && !empty($node['assigned_backup_id'])) {
        $cfError = '';
        $cfUpdated = Cloudflare::updateRecord(
            $node['cf_api_token'],
            $node['zone_id'],
            $node['record_id'],
            $node['domain_name'],
            $node['main_ip'],
            (bool)$node['proxied'],
            $cfError
        );

        if ($cfUpdated) {
            $bStmt = $pdo->prepare("SELECT name, ip FROM backup_nodes WHERE id = ?");
            $bStmt->execute([$node['assigned_backup_id']]);
            $released = $bStmt->fetch();

            $pdo->prepare("
                UPDATE nodes 
                SET current_ip = main_ip, status = 'online', assigned_backup_id = NULL 
                WHERE id = ?
            ")->execute([$node['id']]);

            $pType = strtoupper($node['panel_type']);
            $bText = $released ? "<code>{$released['ip']}</code> ({$released['name']})" : "زاپاس";
            $msg = "🟢 <b>گزارش: بازگشت نود به مدار</b>\n\n"
                 . "🏷 <b>نود:</b> {$node['name']}\n"
                 . "🌍 <b>کشور:</b> {$country}\n"
                 . "👥 <b>گروه:</b> {$node['resolved_group_name']}\n"
                 . "🏢 <b>پنل:</b> {$node['panel_name']} ({$pType})\n"
                 . "🌐 <b>ساب‌دامین:</b> <code>{$node['domain_name']}</code>\n"
                 . "✅ <b>آی‌پی اصلی وصل شد:</b> <code>{$node['main_ip']}</code>\n"
                 . "🔄 <b>نود از روی زاپاس ({$bText}) برداشته شد.</b>\n"
                 . "⏱ <b>زمان:</b> " . date('Y-m-d H:i:s');
            Telegram::sendMessage($msg);
        }
    }
}