<?php
/**
 * Processes one queued Telegram update per invocation.
 * Shared hosting safe cron example:
 *   * * * * * /usr/bin/php /path/to/telegram-bot/worker/telegram_update_worker.php --once >/dev/null 2>&1
 */
declare(strict_types=1);

define('BASE_PATH', dirname(__DIR__));
require_once BASE_PATH . '/src/config.php';

function gemacc_worker_log(string $msg): void {
    $file = BASE_PATH . '/storage/logs/telegram_update_worker.log';
    if (!is_dir(dirname($file))) @mkdir(dirname($file), 0755, true);
    @file_put_contents($file, '[' . date('c') . '] ' . $msg . "\n", FILE_APPEND | LOCK_EX);
}

function gemacc_reserve_update(PDO $pdo): ?array {
    try {
        $pdo->beginTransaction();
        $row = $pdo->query("SELECT * FROM telegram_update_queue WHERE status IN ('PENDING','RETRY') AND attempts < max_attempts ORDER BY received_at ASC, id ASC LIMIT 1 FOR UPDATE")->fetch(PDO::FETCH_ASSOC);
        if (!$row) { $pdo->commit(); return null; }
        $pdo->prepare("UPDATE telegram_update_queue SET status='RUNNING', attempts=attempts+1, reserved_at=NOW(), last_error=NULL WHERE id=?")->execute([(int)$row['id']]);
        $pdo->commit();
        $row['attempts'] = (int)$row['attempts'] + 1;
        return $row;
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        throw $e;
    }
}

$pdo = db();
$row = gemacc_reserve_update($pdo);
if (!$row) {
    echo "NO_JOB\n";
    exit(0);
}

$queueId = (int)$row['id'];
$completed = false;
register_shutdown_function(function() use (&$completed, $queueId) {
    try {
        $pdo = db();
        $err = error_get_last();
        if ($err && in_array((int)$err['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR], true)) {
            $msg = mb_substr(($err['message'] ?? 'fatal') . ' at ' . ($err['file'] ?? '') . ':' . ($err['line'] ?? ''), 0, 900, 'UTF-8');
            $pdo->prepare("UPDATE telegram_update_queue SET status=IF(attempts>=max_attempts,'FAILED','RETRY'), last_error=?, failed_at=IF(attempts>=max_attempts,NOW(),failed_at) WHERE id=?")->execute([$msg, $queueId]);
            gemacc_worker_log('FAILED queue_id=' . $queueId . ' error=' . $msg);
            return;
        }
        if (!$completed) {
            $pdo->prepare("UPDATE telegram_update_queue SET status='DONE', processed_at=NOW() WHERE id=?")->execute([$queueId]);
            gemacc_worker_log('DONE queue_id=' . $queueId);
        }
    } catch (Throwable $e) {
        gemacc_worker_log('shutdown update failed queue_id=' . $queueId . ' error=' . $e->getMessage());
    }
});

try {
    $GLOBALS['__update_override_raw'] = (string)$row['payload_json'];
    require BASE_PATH . '/src/legacy/bot.php';
    $completed = true;
    $pdo->prepare("UPDATE telegram_update_queue SET status='DONE', processed_at=NOW() WHERE id=?")->execute([$queueId]);
} catch (Throwable $e) {
    $msg = mb_substr($e->getMessage(), 0, 900, 'UTF-8');
    $pdo->prepare("UPDATE telegram_update_queue SET status=IF(attempts>=max_attempts,'FAILED','RETRY'), last_error=?, failed_at=IF(attempts>=max_attempts,NOW(),failed_at) WHERE id=?")->execute([$msg, $queueId]);
    gemacc_worker_log('ERROR queue_id=' . $queueId . ' error=' . $msg);
    exit(1);
}
