
<?php
// --- webhook_ecash.php ---
// This script securely handles the callback from ecash and updates user wallets.

// Include necessary files
require_once "../../jwtconnect.php"; // Adjust path as needed
require_once "ecash_config.php"; // Adjust path as needed

define("BASE_URL", "https://wl.tripz-egypt.com/v1/main/ride");
define("LOG_FILE", "../logs/ecash_webhook.log");

// --- Start Webhook Processing ---

// 1. Log the raw incoming data from ecash
$raw_post_data = file_get_contents('php://input');
logError("0", "Webhook received", ["payload" => $raw_post_data]);

$data = json_decode($raw_post_data, true);
if (!$data) {
    logError("0.1", "Invalid JSON payload.");
    http_response_code(400);
    exit;
}

// 2. Extract data and verify the token from ecash
$isSuccess = $data['isSuccess'] ?? null;
$orderRef = $data['orderRef'] ?? null;
$transactionNo = $data['transactionNo'] ?? null;
$amount = $data['amount'] ?? null;
$receivedToken = $data['token'] ?? '';

$string_to_hash = ECASH_MERCHANT_ID . ECASH_MERCHANT_SECRET . $transactionNo . $amount . $orderRef;
$expected_token = md5($string_to_hash);

if (strcasecmp($expected_token, $receivedToken) !== 0) {
    logError("1", "Token Mismatch", [
        "expected" => $expected_token,
        "received" => $receivedToken,
        "string" => $string_to_hash
    ]);
    http_response_code(401); // Unauthorized
    exit;
}
logError("1", "Token Verified Successfully.");

// 3. Check if payment was successful
if ($isSuccess !== true) {
    logError("2", "Payment was not successful according to ecash.", $data);
    // Optionally, update your database to mark the order as 'failed'
    updateTransactionStatus($orderRef, 'failed', $transactionNo);
    http_response_code(200); // Respond OK to ecash, but do nothing else
    exit;
}
logError("2", "Payment reported as SUCCESS by ecash.");

// 4. Find and process the transaction atomically
try {
    $con->beginTransaction();

    $stmt = $con->prepare("SELECT * FROM ecash_transactions WHERE order_ref = ? LIMIT 1 FOR UPDATE");
    $stmt->execute([$orderRef]);
    $transaction = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$transaction) {
        $con->rollBack();
        logError("3", "OrderRef not found in our database.", ["orderRef" => $orderRef]);
        http_response_code(404);
        exit;
    }

    if ($transaction['status'] !== 'pending') {
        $con->rollBack();
        logError("3.1", "Transaction already processed.", ["orderRef" => $orderRef, "status" => $transaction['status']]);
        http_response_code(200);
        exit;
    }

    // Atomically mark as processing to prevent concurrent webhooks
    $lockStmt = $con->prepare("UPDATE ecash_transactions SET status = 'processing' WHERE order_ref = ? AND status = 'pending'");
    $lockStmt->execute([$orderRef]);
    if ($lockStmt->rowCount() === 0) {
        $con->rollBack();
        logError("3.2", "Concurrent webhook detected, transaction already claimed.", ["orderRef" => $orderRef]);
        http_response_code(200);
        exit;
    }

    $passengerId = $transaction['passenger_id'];
    $paidAmount = $transaction['amount'];
    logError("3", "Transaction found in DB.", ["passengerId" => $passengerId, "amount" => $paidAmount]);

    $finalAmount = calculateBonus($paidAmount);
    logError("4", "Bonus calculated.", ["original" => $paidAmount, "final" => $finalAmount]);

    $passengerToken = generatePaymentToken($passengerId, $finalAmount);
    if ($passengerToken) {
        addToPassengerWallet($passengerId, $finalAmount, $passengerToken);
    }

    $paymentMethod = 'ecash';
    addToSiroWallet($passengerId, $paidAmount, $paymentMethod);

    $stmtUpdate = $con->prepare("UPDATE ecash_transactions SET status = 'success', ecash_transaction_no = ?, updated_at = NOW() WHERE order_ref = ?");
    $stmtUpdate->execute([$transactionNo, $orderRef]);

    $con->commit();
    logError("7", "Process completed successfully.");

} catch (PDOException $e) {
    logError("DB_ERROR", "Database error: " . $e->getMessage());
    http_response_code(500);
    exit;
} catch (Exception $e) {
    logError("GENERAL_ERROR", "General error: " . $e->getMessage());
    http_response_code(500);
    exit;
}

// 7. Respond to ecash server
http_response_code(200);
echo "Webhook processed.";


// --- ALL HELPER FUNCTIONS FROM paymet_verfy.php ---

function updateTransactionStatus($orderRef, $status, $transactionNo) {
    global $con;
    try {
        $stmt = $con->prepare(
            "UPDATE ecash_transactions SET status = ?, ecash_transaction_no = ?, updated_at = NOW() WHERE order_ref = ?"
        );
        $stmt->execute([$status, $transactionNo, $orderRef]);
    } catch (PDOException $e) {
        logError("DB_UPDATE_ERROR", "Failed to update transaction status", ["error" => $e->getMessage()]);
    }
}




function generatePaymentToken($passengerId, $amount) {
    $url = BASE_URL . "/passengerWallet/addPaymentTokenPassenger.php";
    
    $postData = [
        'passengerId' => $passengerId,
        'amount' => $amount
    ];
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);
    
    if ($curlError) {
        logError("4.1", "cURL error in token generation", [
            "error" => $curlError,
            "url" => $url
        ]);
        return null;
    }
    
    if ($httpCode != 200) {
        logError("4.2", "HTTP error in token generation", [
            "http_code" => $httpCode,
            "response" => $response
        ]);
        return null;
    }
    
    $data = json_decode($response, true);
    
    if (!$data || !isset($data['message'])) {
        logError("4.3", "Invalid response format in token generation", [
            "response" => $response
        ]);
        return null;
    }
    
    return $data['message']; // ✅ Return token
}

// 🎯 Function to add balance to passenger's wallet with error logging
function addToPassengerWallet($passengerId, $amount, $token) {
    $url = BASE_URL . "/passengerWallet/add.php";
    
    $postData = [
        'passenger_id' => $passengerId,
        'balance' => $amount,
        'token' => $token
    ];
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);
    
    if ($curlError) {
        logError("5.1", "cURL error in passenger wallet update", [
            "error" => $curlError,
            "url" => $url
        ]);
        return null;
    }
    
    if ($httpCode != 200) {
        logError("5.2", "HTTP error in passenger wallet update", [
            "http_code" => $httpCode,
            "response" => $response
        ]);
        return null;
    }
    
    $data = json_decode($response, true);
    
    if (!$data) {
        logError("5.3", "Invalid response format in passenger wallet update", [
            "response" => $response
        ]);
        return null;
    }
    
    return $data; // ✅ Return result
}

// 🎯 Function to add balance to Siro wallet with error logging


function addToSiroWallet($passengerId, $amount, $paymentMethod) {
   
    
    // Generate a new token specifically for the Siro wallet
    $siroToken = generatePaymentToken($passengerId, $amount);
    
    if (!$siroToken) {
        logError("6.0.1", "Failed to generate Siro token");
        return null;
    }
    
    logError("6.0.2", "Generated new Siro token", [
        "token_length" => ($siroToken)
    ]);
    
    $url = BASE_URL . "/siroWallet/add.php";
    
    $postData = [
        'amount' => $amount,
        'paymentMethod' => $paymentMethod,
        'passengerId' => $passengerId,
        'token' => $siroToken,  // Use the new Siro-specific token
        'driverId' => 'passenger'
    ];
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);
    
    if ($curlError) {
        logError("6.1", "cURL error in Siro wallet update", [
            "error" => $curlError,
            "url" => $url
        ]);
        return null;
    }
    
    if ($httpCode != 200) {
        logError("6.2", "HTTP error in Siro wallet update", [
            "http_code" => $httpCode,
            "response" => $response
        ]);
        return null;
    }
    
    $data = json_decode($response, true);
    
    if (!$data) {
        logError("6.3", "Invalid response format in Siro wallet update", [
            "response" => $response
        ]);
        return null;
    }
    
    return $data; // ✅ Return result
}


// 🎯 Function to calculate bonus
function calculateBonus($amount) {
    logError("3.1", "Bonus calculation input", ["amount" => $amount]);
    
    $result = 0;
    if ($amount == 100) $result = 100;
    else if ($amount == 200) $result = 215;
    else if ($amount == 400) $result = 450;
    else if ($amount == 1000) $result = 1140;
    
    logError("3.2", "Bonus calculation result", [
        "input" => $amount, 
        "output" => $result
    ]);
    
    return $result;
}
?>