<?php
require_once '../config.php';

// Enforce Rate Limiting on financial transactions (Max 10 per minute per IP)
checkRateLimit('transaction', 10, 60);

$data = json_decode(file_get_contents("php://input"), true);

if (empty($data['user_id']) || empty($data['action']) || !isset($data['amount'])) {
    http_response_code(400);
    echo json_encode(["status" => "error", "message" => "All fields (user_id, action, amount) are required."]);
    exit();
}

$userId = intval($data['user_id']);
$action = sanitizeInput($data['action']); // 'topup' or 'withdraw'
$amount = floatval($data['amount']);
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';

if ($amount <= 0) {
    http_response_code(400);
    echo json_encode(["status" => "error", "message" => "Transaction amount must be greater than zero."]);
    exit();
}

try {
    $db = getDBConnection();

    // Start database transaction block
    $db->beginTransaction();

    // Lock user wallet row for update to prevent race conditions (anti-concurrency exploit!)
    $stmt = $db->prepare("SELECT balance FROM wallets WHERE user_id = ? FOR UPDATE");
    $stmt->execute([$userId]);
    $wallet = $stmt->fetch();

    if (!$wallet) {
        // Fallback: Create wallet if not exists
        $stmt = $db->prepare("INSERT INTO wallets (user_id, balance, today_winnings) VALUES (?, 0.00, 0.00)");
        $stmt->execute([$userId]);
        $current_balance = 0.00;
    } else {
        $current_balance = floatval($wallet['balance']);
    }

    $balance_before = $current_balance;

    if ($action === 'topup' || $action === 'referral' || $action === 'reward') {
        $balance_after = $current_balance + $amount;
    } else if ($action === 'withdraw') {
        if ($current_balance < $amount) {
            http_response_code(400);
            echo json_encode(["status" => "error", "message" => "Anti-Fraud: Insufficient wallet balance for withdrawal."]);
            exit();
        }
        $balance_after = $current_balance - $amount;
    } else {
        http_response_code(400);
        echo json_encode(["status" => "error", "message" => "Invalid transaction action."]);
        exit();
    }

    // Update wallet balance
    $stmt = $db->prepare("UPDATE wallets SET balance = ? WHERE user_id = ?");
    $stmt->execute([$balance_after, $userId]);

    // Generate unique transaction reference using secure entropy
    $reference = uniqid('TXN-' . strtoupper(substr($action, 0, 3)) . '-', true);

    // Insert into Immutable Audit Log Table
    $stmt = $db->prepare("INSERT INTO wallet_transactions (user_id, action, amount, balance_before, balance_after, reference, ip_address) VALUES (?, ?, ?, ?, ?, ?, ?)");
    $stmt->execute([$userId, $action, $amount, $balance_before, $balance_after, $reference, $ip]);

    // Commit transaction securely
    $db->commit();

    echo json_encode([
        "status" => "success",
        "message" => "Transaction successfully processed and audited.",
        "reference" => $reference,
        "new_balance" => $balance_after
    ]);

} catch(PDOException $e) {
    if (isset($db) && $db->inTransaction()) {
        $db->rollBack();
    }
    logSecurityError("Wallet Transaction Failure (User ID: $userId, Action: $action): " . $e->getMessage());
    http_response_code(500);
    echo json_encode(["status" => "error", "message" => "Transaction processing failed. Security rollback executed."]);
}
?>
