<?php
/**
 * CRON worker: processes queued rewards jobs.
 *
 * Example cron:
 * */

if (php_sapi_name() !== 'cli') {
    if (!isset($_SERVER['REMOTE_ADDR']) || $_SERVER['REMOTE_ADDR'] !== '127.0.0.1') {
        die('Access denied - tylko z CLI lub localhost');
    }
}

error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);

require_once __DIR__ . '/../administration/includes/config.php';

if (!isset($pdo) || !($pdo instanceof PDO)) {
    die("DB not initialized\n");
}

function logLine($s) {
    echo '[' . date('Y-m-d H:i:s') . '] ' . $s . "\n";
}

$limit = 50;

// Claim jobs (simple approach: select queued and update to processing)
$stmt = $pdo->prepare("SELECT id, payload_json, attempts FROM rewards_jobs WHERE status = 'queued' ORDER BY created_at ASC LIMIT :lim");
$stmt->bindValue(':lim', $limit, PDO::PARAM_INT);
$stmt->execute();
$jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($jobs as $job) {
    $jobId = (int) $job['id'];

    // optimistic lock
    $upd = $pdo->prepare("UPDATE rewards_jobs SET status = 'processing', attempts = attempts + 1 WHERE id = :id AND status = 'queued'");
    $upd->execute([':id' => $jobId]);
    if ($upd->rowCount() === 0) continue;

    $payload = json_decode($job['payload_json'], true);
    if (!$payload) {
        $fail = $pdo->prepare("UPDATE rewards_jobs SET status = 'failed', last_error = :err WHERE id = :id");
        $fail->execute([':id' => $jobId, ':err' => 'Invalid payload JSON']);
        continue;
    }

    // TODO: tutaj wstaw Waszą logikę nagród:
    // - policz nagrodę na podstawie stawki/rate, wyniku, itd.
    // - dopisz transakcje do tabeli `transactions`
    // - zaktualizuj `user_stats.balance`
    // - zwróć strukturę pod animacje w UI (np. coins, xp, items)

    $winnerId = (int)($payload['winnerUserId'] ?? 0);
    $loserId = (int)($payload['loserUserId'] ?? 0);

    // Minimalny przykład: +1.00 dla zwycięzcy, +0.20 dla przegranego
    // TODO: podmień na Waszą logikę (stawka/rate/ligy/tabele nagród)
    $winnerReward = 1.00;
    $loserReward = 0.20;

    $matchId = (int)($payload['matchId'] ?? 0);
    $score = (string)($payload['score'] ?? '');

    try {
        $pdo->beginTransaction();

        // ensure user_stats exists
        $pdo->prepare("INSERT IGNORE INTO user_stats (user_id, balance, matches_played, matches_won, matches_lost, matches_draw, tournaments_played, tournaments_won, leagues_participated, total_income, total_expenses, total_transactions, account_status)
                       VALUES (?, 0, 0,0,0,0,0,0,0,0,0,0,'active')")
            ->execute([$winnerId]);
        $pdo->prepare("INSERT IGNORE INTO user_stats (user_id, balance, matches_played, matches_won, matches_lost, matches_draw, tournaments_played, tournaments_won, leagues_participated, total_income, total_expenses, total_transactions, account_status)
                       VALUES (?, 0, 0,0,0,0,0,0,0,0,0,0,'active')")
            ->execute([$loserId]);

        // Update stats + balance
        $pdo->prepare("UPDATE user_stats 
                       SET balance = balance + ?,
                           matches_played = matches_played + 1,
                           matches_won = matches_won + 1,
                           total_income = total_income + ?,
                           total_transactions = total_transactions + 1
                       WHERE user_id = ?")
            ->execute([$winnerReward, $winnerReward, $winnerId]);

        $pdo->prepare("UPDATE user_stats 
                       SET balance = balance + ?,
                           matches_played = matches_played + 1,
                           matches_lost = matches_lost + 1,
                           total_income = total_income + ?,
                           total_transactions = total_transactions + 1
                       WHERE user_id = ?")
            ->execute([$loserReward, $loserReward, $loserId]);

        // Insert transactions (if table exists)
        // Schema inferred from mds/transactions_add_example.sql: (user_id, type, amount, title, description, category)
        $pdo->exec("CREATE TABLE IF NOT EXISTS transactions (
            id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            user_id BIGINT UNSIGNED NOT NULL,
            type VARCHAR(20) NOT NULL,
            amount DECIMAL(12,2) NOT NULL,
            title VARCHAR(255) NOT NULL,
            description TEXT NULL,
            category VARCHAR(50) NULL,
            created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
            INDEX idx_user_created (user_id, created_at)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

        $tx = $pdo->prepare("INSERT INTO transactions (user_id, type, amount, title, description, category) VALUES (?, 'income', ?, ?, ?, ?)");

        $titleW = 'Ping-Pong 1v1 - wygrana';
        $descW = 'Mecz #' . $matchId . ' wynik ' . $score;
        $tx->execute([$winnerId, $winnerReward, $titleW, $descW, 'match']);

        $titleL = 'Ping-Pong 1v1 - udział';
        $descL = 'Mecz #' . $matchId . ' wynik ' . $score;
        $tx->execute([$loserId, $loserReward, $titleL, $descL, 'match']);

        $result = [
            'winner' => ['userId' => $winnerId, 'reward' => (float)$winnerReward, 'currency' => 'balance'],
            'loser' => ['userId' => $loserId, 'reward' => (float)$loserReward, 'currency' => 'balance'],
            'animation' => ['type' => 'coins', 'durationMs' => 2500],
            'match' => ['matchId' => $matchId, 'score' => $score]
        ];

        $ok = $pdo->prepare("UPDATE rewards_jobs SET status = 'done', result_json = :res, last_error = NULL WHERE id = :id");
        $ok->execute([':id' => $jobId, ':res' => json_encode($result, JSON_UNESCAPED_UNICODE)]);

        $pdo->commit();
        logLine("Job #$jobId done");
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        $fail = $pdo->prepare("UPDATE rewards_jobs SET status = 'failed', last_error = :err WHERE id = :id");
        $fail->execute([':id' => $jobId, ':err' => $e->getMessage()]);
        logLine("Job #$jobId failed: " . $e->getMessage());
    }
}
