<?php
// This is the Instant Payment Notification (IPN) listener.
// It runs in the background when PayPal sends a notification.
// It should not output any HTML.

require_once 'includes/db.php';

// Function to log messages for debugging
function log_ipn_message($message) {
    file_put_contents('ipn_log.txt', date('[Y-m-d H:i:s] ') . $message . "\n", FILE_APPEND);
}

log_ipn_message("IPN Listener Accessed.");

// Read the raw POST data from PayPal
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
    $keyval = explode('=', $keyval);
    if (count($keyval) == 2) {
        $myPost[$keyval[0]] = urldecode($keyval[1]);
    }
}

// Add 'cmd=_notify-validate' to the request
$req = 'cmd=_notify-validate';
foreach ($myPost as $key => $value) {
    $value = urlencode($value);
    $req .= "&$key=$value";
}

// Fetch PayPal settings from the database
$settings_sql = "SELECT * FROM site_settings WHERE setting_name LIKE 'paypal_%'";
$settings_result = $conn->query($settings_sql);
$settings = [];
while ($row = $settings_result->fetch_assoc()) {
    $settings[$row['setting_name']] = $row['setting_value'];
}
$paypal_url = $settings['paypal_sandbox_mode'] == '1' ? 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr' : 'https://ipnpb.paypal.com/cgi-bin/webscr';
$merchant_email = $settings['paypal_email'];
$currency = $settings['paypal_currency'];

log_ipn_message("Verifying IPN with PayPal at: " . $paypal_url);
log_ipn_message("Request: " . $req);

// Post the data back to PayPal for validation
$ch = curl_init($paypal_url);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));
$res = curl_exec($ch);
curl_close($ch);

log_ipn_message("PayPal Response: " . $res);

// If PayPal response is VERIFIED, process the payment
if (strcmp(trim($res), 'VERIFIED') == 0) {
    log_ipn_message("IPN VERIFIED. Processing payment.");

    // Assign posted variables to local variables
    $payment_status = $_POST['payment_status'];
    $receiver_email = $_POST['receiver_email'];
    $mc_gross = $_POST['mc_gross'];
    $mc_currency = $_POST['mc_currency'];
    $txn_id = $_POST['txn_id'];
    $user_id = (int)$_POST['custom'];

    log_ipn_message("Payment Status: $payment_status, Receiver Email: $receiver_email, Amount: $mc_gross $mc_currency, TXN_ID: $txn_id, User ID: $user_id");

    // --- Security and Business Logic Checks ---
    // 1. Check that the payment status is "Completed"
    if ($payment_status !== 'Completed') {
        log_ipn_message("Verification failed: Payment status is not 'Completed'.");
        exit();
    }
    // 2. Check that the receiver_email is your PayPal merchant email
    if (strtolower($receiver_email) !== strtolower($merchant_email)) {
        log_ipn_message("Verification failed: Receiver email does not match merchant email.");
        exit();
    }
    // 3. Check that the currency is correct
    if ($mc_currency !== $currency) {
        log_ipn_message("Verification failed: Currency does not match.");
        exit();
    }
    // 4. Check that the transaction ID has not been previously processed
    $stmt_check = $conn->prepare("SELECT id FROM transactions WHERE reference_number = ?");
    $stmt_check->bind_param("s", $txn_id);
    $stmt_check->execute();
    $stmt_check->store_result();
    if ($stmt_check->num_rows > 0) {
        log_ipn_message("Verification failed: Transaction ID has already been processed.");
        exit();
    }
    $stmt_check->close();

    // --- All checks passed. Update the user's account. ---
    log_ipn_message("All checks passed. Crediting user account.");
    
    $conn->begin_transaction();
    try {
        // Add funds to user's wallet
        $stmt_wallet = $conn->prepare("UPDATE users SET wallet_balance = wallet_balance + ? WHERE id = ?");
        $stmt_wallet->bind_param("di", $mc_gross, $user_id);
        $stmt_wallet->execute();

        // Insert a record of the transaction
        $stmt_trans = $conn->prepare("INSERT INTO transactions (user_id, transaction_type, amount, payment_method, reference_number, status) VALUES (?, 'Top-up', ?, 'PayPal', ?, 'Completed')");
        $stmt_trans->bind_param("ids", $user_id, $mc_gross, $txn_id);
        $stmt_trans->execute();

        $conn->commit();
        log_ipn_message("SUCCESS: User $user_id credited with $mc_gross $mc_currency.");
    } catch (mysqli_sql_exception $e) {
        $conn->rollback();
        log_ipn_message("DATABASE ERROR: " . $e->getMessage());
    }

} else if (strcmp($res, 'INVALID') == 0) {
    log_ipn_message("IPN INVALID.");
}
?>
