<?php
declare(strict_types=1);
/**
 * cron_runner.php — PHP self-cron
 * Include at the top of any page to trigger cron_check.php every 60 seconds.
 * Throttled by DB timestamp so concurrent requests don't pile up.
 *
 * Usage: require_once __DIR__ . '/cron_runner.php';
 * cPanel Cron command (every 5 min):
 *   curl -s "https://ludoking.gamingserver.win/api/cron_check.php" > /dev/null 2>&1
 */

require_once __DIR__ . '/db.php';

define('LK_CRON_INTERVAL', 60); // seconds between runs
define('LK_CRON_KEY',      'cron_last_run');
define('LK_CRON_ENDPOINT', LK_SITE_URL . '/api/cron_check.php');

function lk_maybe_run_cron(): void {
    // ~10% of page loads actually check the DB (reduces overhead)
    if (mt_rand(0, 9) !== 0) return;

    try {
        $pdo = lk_pdo();
        $st = $pdo->prepare("SELECT value FROM settings WHERE `key`=? LIMIT 1");
        $st->execute([LK_CRON_KEY]);
        $row = $st->fetch(PDO::FETCH_ASSOC);
        $lastRun = $row ? (int)$row['value'] : 0;

        if (time() - $lastRun < LK_CRON_INTERVAL) return;

        // Claim the lock
        $pdo->prepare(
            "INSERT INTO settings (`key`,`value`) VALUES (?,?) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)"
        )->execute([LK_CRON_KEY, (string)time()]);

        // Fire async cURL (non-blocking — 5s timeout, don't wait for response)
        $secret = lk_setting('cron_secret', '');
        $url    = LK_CRON_ENDPOINT . ($secret !== '' ? '?secret=' . urlencode($secret) : '');

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT        => 5,
            CURLOPT_CONNECTTIMEOUT => 3,
            CURLOPT_NOSIGNAL       => true,
            CURLOPT_SSL_VERIFYPEER => false,
        ]);
        curl_exec($ch);
        curl_close($ch);
    } catch (Throwable $e) {
        // Silently ignore — cron is best-effort
    }
}

// If called directly (browser or cPanel curl), run immediately and return JSON
if (basename($_SERVER['PHP_SELF'] ?? '') === 'cron_runner.php' && php_sapi_name() !== 'cli') {
    header('Content-Type: application/json; charset=utf-8');
    try {
        $pdo = lk_pdo();

        // Close expired assigned rooms (10 min timer)
        $closed = (int)$pdo->exec("
            UPDATE rooms SET status='closed', closed_at=NOW()
            WHERE status='assigned' AND expires_at IS NOT NULL AND expires_at < NOW()
        ");

        // Close stale waiting rooms (expires_at passed OR 15 min since created if no expires_at)
        $expired = (int)$pdo->exec("
            UPDATE rooms SET status='closed', closed_at=NOW()
            WHERE status='waiting' AND is_assigned=0
              AND (
                (expires_at IS NOT NULL AND expires_at < NOW())
                OR (expires_at IS NULL AND created_at < DATE_SUB(NOW(), INTERVAL 15 MINUTE))
              )
        ");

        // Reset ghost assigned rows
        $reset = (int)$pdo->exec("
            UPDATE rooms SET is_assigned=0, status='waiting',
                assigned_at=NULL, expires_at=NULL, assigned_to=NULL, instance_id=NULL
            WHERE is_assigned=1 AND status='waiting'
              AND assigned_at IS NOT NULL AND assigned_at < DATE_SUB(NOW(), INTERVAL 30 MINUTE)
        ");

        // Delete screenshots older than 24h
        $uploadBase = __DIR__ . '/';
        $ssDeleted  = 0;
        $stale = $pdo->query("
            SELECT id, screenshot_path FROM rooms
            WHERE screenshot_path IS NOT NULL AND screenshot_path != ''
              AND created_at < DATE_SUB(NOW(), INTERVAL 24 HOUR)
        ");
        $staleRows = $stale ? $stale->fetchAll(PDO::FETCH_ASSOC) : [];
        $idsToClean = [];
        foreach ($staleRows as $row) {
            $fp = $uploadBase . trim((string)($row['screenshot_path'] ?? ''));
            if (is_file($fp)) { @unlink($fp); $ssDeleted++; }
            $idsToClean[] = (int)$row['id'];
        }
        if (!empty($idsToClean)) {
            $ph = implode(',', array_fill(0, count($idsToClean), '?'));
            $pdo->prepare("UPDATE rooms SET screenshot_path=NULL WHERE id IN ($ph)")->execute($idsToClean);
        }

        $pdo->prepare("INSERT INTO settings (`key`,`value`) VALUES (?,?) ON DUPLICATE KEY UPDATE `value`=VALUES(`value`)")
            ->execute([LK_CRON_KEY, (string)time()]);

        echo json_encode([
            'ok'      => true,
            'closed'  => $closed,
            'expired' => $expired,
            'reset'   => $reset,
            'time'    => date('Y-m-d H:i:s'),
        ], JSON_UNESCAPED_UNICODE);
    } catch (Throwable $e) {
        echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
    }
    exit;
}

// When included from another page:
lk_maybe_run_cron();
