<?php
//Developer: core tech web designTechnology
//Whatsapp: +2349162671360
//Telegram: @jeditech

if (session_status() === PHP_SESSION_NONE) { session_start(); }
require_once '../include/config.php';

// ── Auth guard ────────────────────────────────────────────────────────────
if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true) {
    header('Location: ../signin.php');
    exit();
}

// ── Inputs ────────────────────────────────────────────────────────────────
$reference = isset($_GET['reference']) ? trim($_GET['reference']) : '';
$gateway   = isset($_GET['gateway'])   ? trim($_GET['gateway'])   : 'paystack';

if (empty($reference)) {
    $_SESSION['error'] = "Invalid transaction reference.";
    header('Location: fund-wallet');
    exit();
}

// ── Gateway verification ───────────────────────────────────────────────────
$verified      = false;
$amount        = 0;
$gateway_ref   = $reference;
$payment_method = 'card';
$gateway_response_raw = '';

if ($gateway === 'korapay') {
    // ── Korapay verification ───────────────────────────────────────────
    $korapay_secret_key = $site_data['korapay_secret_key'];

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL            => "https://api.korapay.com/merchant/api/v1/charges/" . rawurlencode($reference),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => "",
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST  => "GET",
        CURLOPT_HTTPHEADER     => [
            "Authorization: Bearer " . $korapay_secret_key,
            "Cache-Control: no-cache",
        ],
    ]);

    $response = curl_exec($curl);
    $err      = curl_error($curl);
    curl_close($curl);

    if ($err) {
        $_SESSION['error'] = "Unable to verify Korapay payment. Please contact support.";
        header('Location: fund-wallet');
        exit();
    }

    $gateway_response_raw = $response;
    $result = json_decode($response, true);

    if (
        isset($result['status']) && $result['status'] === true &&
        isset($result['data']['status']) && $result['data']['status'] === 'success'
    ) {
        $verified       = true;
        $amount         = floatval($result['data']['amount']);
        $gateway_ref    = $result['data']['reference'];
        $payment_method = isset($result['data']['payment_method']) ? $result['data']['payment_method'] : 'card';
    }

} elseif ($gateway === 'cryptomus') {
    // ── Cryptomus verification (poll payment status by order_id) ──────
    $cryptomus_merchant_id = $site_data['cryptomus_merchant_id'];
    $cryptomus_payment_key = $site_data['cryptomus_payment_key'];
    $usd_to_ngn            = floatval($site_data['usd_to_ngn'] ?? 1600.00);

    // Fetch the pending transaction first to get the NGN amount stored
    $txn_check = $pdo->prepare("SELECT * FROM transactions WHERE transaction_ref = :ref AND user_id = :uid");
    $txn_check->execute(['ref' => $reference, 'uid' => $_SESSION['user_id']]);
    $pending_txn = $txn_check->fetch(PDO::FETCH_ASSOC);

    if (!$pending_txn) {
        $_SESSION['error'] = "Transaction not found.";
        header('Location: fund-wallet');
        exit();
    }

    // Already credited? Skip re-verification
    if ($pending_txn['status'] === 'successful') {
        $_SESSION['success'] = "Payment already processed successfully.";
        header('Location: fund-wallet');
        exit();
    }

    // Query Cryptomus payment status by order_id
    $payload      = json_encode(['order_id' => $reference]);
    $sign         = md5(base64_encode($payload) . $cryptomus_payment_key);

    $curl = curl_init('https://api.cryptomus.com/v1/payment/info');
    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $payload,
        CURLOPT_HTTPHEADER     => [
            'Content-Type: application/json',
            'merchant: ' . $cryptomus_merchant_id,
            'sign: '     . $sign,
        ],
        CURLOPT_TIMEOUT        => 30,
    ]);

    $response = curl_exec($curl);
    $err      = curl_error($curl);
    curl_close($curl);

    if ($err) {
        $_SESSION['error'] = "Unable to verify crypto payment. Please contact support.";
        header('Location: fund-wallet');
        exit();
    }

    $gateway_response_raw = $response;
    $result = json_decode($response, true);

    // Cryptomus paid statuses: paid, paid_over, wrong_amount (partially), confirm_check
    $paid_statuses = ['paid', 'paid_over', 'confirm_check'];

    if (
        isset($result['result']['status']) &&
        in_array($result['result']['status'], $paid_statuses, true)
    ) {
        $verified       = true;
        // Use the NGN amount stored in our DB (we created the invoice in USD but track in NGN)
        $amount         = floatval($pending_txn['amount']);
        $gateway_ref    = $result['result']['uuid'] ?? $reference;
        $payment_method = 'crypto_' . strtolower($result['result']['currency'] ?? 'crypto');
    } elseif (
        isset($result['result']['status']) &&
        $result['result']['status'] === 'wrong_amount'
    ) {
        // User paid but wrong amount — mark failed and inform user
        $pdo->prepare("UPDATE transactions SET status='failed', gateway_response=:gresp, updated_at=NOW() WHERE transaction_ref=:ref")
            ->execute(['gresp' => $gateway_response_raw, 'ref' => $reference]);
        $_SESSION['error'] = "Crypto payment amount mismatch. Please contact support with your transaction reference: " . htmlspecialchars($reference);
        header('Location: fund-wallet');
        exit();
    } elseif (
        isset($result['result']['status']) &&
        in_array($result['result']['status'], ['cancel', 'fail', 'system_fail'], true)
    ) {
        $pdo->prepare("UPDATE transactions SET status='failed', gateway_response=:gresp, updated_at=NOW() WHERE transaction_ref=:ref")
            ->execute(['gresp' => $gateway_response_raw, 'ref' => $reference]);
        $_SESSION['error'] = "Crypto payment failed or was cancelled. Please try again.";
        header('Location: fund-wallet');
        exit();
    } else {
        // Payment pending / not yet confirmed — user may have arrived too early
        $_SESSION['error'] = "Your crypto payment is still being confirmed on the blockchain. Please wait a few minutes and refresh this page, or check your transaction history.";
        header('Location: fund-wallet');
        exit();
    }

} elseif ($gateway === 'flutterwave') {
    // ── Flutterwave verification ───────────────────────────────────────
    $flutterwave_secret_key = $site_data['flutterwave_secret_key'];

    $txn_check = $pdo->prepare("SELECT * FROM transactions WHERE transaction_ref = :ref AND user_id = :uid");
    $txn_check->execute(['ref' => $reference, 'uid' => $_SESSION['user_id']]);
    $pending_txn = $txn_check->fetch(PDO::FETCH_ASSOC);

    if (!$pending_txn) {
        $_SESSION['error'] = "Transaction not found.";
        header('Location: fund-wallet');
        exit();
    }

    if ($pending_txn['status'] === 'successful') {
        $_SESSION['success'] = "Payment already processed successfully.";
        header('Location: fund-wallet');
        exit();
    }

    $curl = curl_init('https://api.flutterwave.com/v3/transactions/verify_by_reference?tx_ref=' . rawurlencode($reference));
    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . $flutterwave_secret_key,
            'Cache-Control: no-cache',
        ],
        CURLOPT_TIMEOUT => 30,
    ]);

    $response = curl_exec($curl);
    $err      = curl_error($curl);
    curl_close($curl);

    if ($err) {
        $_SESSION['error'] = "Unable to verify Flutterwave payment. Please contact support.";
        header('Location: fund-wallet');
        exit();
    }

    $gateway_response_raw = $response;
    $result = json_decode($response, true);

    if (
        isset($result['status']) && $result['status'] === 'success' &&
        isset($result['data']['status']) && in_array($result['data']['status'], ['successful', 'completed'], true)
    ) {
        $verified       = true;
        $amount         = floatval($pending_txn['amount']);
        $gateway_ref    = $result['data']['id'] ?? $reference;
        $payment_method = $result['data']['payment_type'] ?? 'card';
    } else {
        $pdo->prepare("UPDATE transactions SET status='failed', gateway_response=:gresp, updated_at=NOW() WHERE transaction_ref=:ref")
            ->execute(['gresp' => $gateway_response_raw, 'ref' => $reference]);
        $_SESSION['error'] = "Flutterwave payment could not be confirmed yet. Please try again or contact support.";
        header('Location: fund-wallet');
        exit();
    }

} else {
    // ── Paystack verification ──────────────────────────────────────────
    $paystack_secret_key = $site_data['paystack_secret_key'];

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL            => "https://api.paystack.co/transaction/verify/" . rawurlencode($reference),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING       => "",
        CURLOPT_MAXREDIRS      => 10,
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST  => "GET",
        CURLOPT_HTTPHEADER     => [
            "Authorization: Bearer " . $paystack_secret_key,
            "Cache-Control: no-cache",
        ],
    ]);

    $response = curl_exec($curl);
    $err      = curl_error($curl);
    curl_close($curl);

    if ($err) {
        $_SESSION['error'] = "Unable to verify Paystack payment. Please contact support.";
        header('Location: fund-wallet');
        exit();
    }

    $gateway_response_raw = $response;
    $result = json_decode($response, true);

    if (
        isset($result['status']) && $result['status'] === true &&
        isset($result['data']['status']) && $result['data']['status'] === 'success'
    ) {
        $verified       = true;
        $amount         = floatval($result['data']['amount']) / 100; // kobo → naira
        $gateway_ref    = $result['data']['reference'];
        $payment_method = isset($result['data']['channel']) ? $result['data']['channel'] : 'card';
    }
}

// ── Process verified payment ───────────────────────────────────────────────
if ($verified) {
    try {
        $pdo->beginTransaction();

        // Fetch the pending transaction
        $stmt = $pdo->prepare("SELECT * FROM transactions WHERE transaction_ref = :ref FOR UPDATE");
        $stmt->execute(['ref' => $reference]);
        $transaction = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$transaction) {
            throw new Exception("Transaction record not found.");
        }

        // Prevent double-processing
        if ($transaction['status'] === 'successful') {
            $pdo->rollBack();
            $_SESSION['success'] = "Payment already processed successfully.";
            header('Location: fund-wallet');
            exit();
        }

        // ── 1. Mark transaction successful ──────────────────────────────
        $pdo->prepare(
            "UPDATE transactions
             SET status = 'successful',
                 payment_method     = :pm,
                 gateway_reference  = :gref,
                 gateway_response   = :gresp,
                 updated_at         = NOW()
             WHERE transaction_ref  = :ref"
        )->execute([
            'pm'    => $payment_method,
            'gref'  => $gateway_ref,
            'gresp' => $gateway_response_raw,
            'ref'   => $reference,
        ]);

        // ── 2. Credit user's main_balance ────────────────────────────────
        $pdo->prepare(
            "UPDATE users SET main_balance = main_balance + :amount WHERE id = :uid"
        )->execute([
            'amount' => $amount,
            'uid'    => $transaction['user_id'],
        ]);

        // ── 3. Referral commission on first deposit ──────────────────────
        if ($transaction['is_first_deposit'] == 1 && !$transaction['referral_awarded']) {

            $referral_stmt = $pdo->prepare(
                "SELECT * FROM referrals WHERE referred_user_id = :uid AND status = 'pending'"
            );
            $referral_stmt->execute(['uid' => $transaction['user_id']]);
            $referral = $referral_stmt->fetch(PDO::FETCH_ASSOC);

            if ($referral) {
                $refer_percent     = floatval($site_data['refer_percent']);
                $commission_amount = ($amount * $refer_percent) / 100;

                $pdo->prepare(
                    "INSERT INTO referral_earnings
                        (referral_id, referrer_id, referred_user_id, transaction_id,
                         deposit_amount, commission_percent, commission_amount, status, credited_at, created_at)
                     VALUES
                        (:rid, :rer, :red, :tid, :dep, :pct, :com, 'credited', NOW(), NOW())"
                )->execute([
                    'rid'  => $referral['id'],
                    'rer'  => $referral['referrer_id'],
                    'red'  => $transaction['user_id'],
                    'tid'  => $transaction['id'],
                    'dep'  => $amount,
                    'pct'  => $refer_percent,
                    'com'  => $commission_amount,
                ]);

                $pdo->prepare(
                    "UPDATE users
                     SET referral_balance = referral_balance + :com,
                         total_earnings   = total_earnings   + :com
                     WHERE id = :rid"
                )->execute([
                    'com' => $commission_amount,
                    'rid' => $referral['referrer_id'],
                ]);

                $pdo->prepare(
                    "UPDATE referrals SET status = 'active', earnings = :com, updated_at = NOW() WHERE id = :rid"
                )->execute(['com' => $commission_amount, 'rid' => $referral['id']]);

                $pdo->prepare(
                    "UPDATE transactions SET referral_awarded = 1 WHERE id = :tid"
                )->execute(['tid' => $transaction['id']]);

                $pdo->prepare(
                    "UPDATE users SET first_activation = 1 WHERE id = :uid"
                )->execute(['uid' => $transaction['user_id']]);
            }
        }

        $pdo->commit();

        $_SESSION['success'] = "Payment successful! Your account has been credited with ₦" . number_format($amount, 2);
        header('Location: fund-wallet');
        exit();

    } catch (Exception $e) {
        $pdo->rollBack();
        $_SESSION['error'] = "Error processing payment: " . $e->getMessage();
        header('Location: fund-wallet');
        exit();
    }

} else {
    // ── Payment failed or verification returned non-success ────────────
    try {
        $pdo->prepare(
            "UPDATE transactions
             SET status = 'failed', gateway_response = :gresp, updated_at = NOW()
             WHERE transaction_ref = :ref"
        )->execute(['gresp' => $gateway_response_raw, 'ref' => $reference]);
    } catch (PDOException $e) {
        // Silently log — don't expose DB errors to user
    }

    $_SESSION['error'] = "Payment verification failed. Please try again or contact support.";
    header('Location: fund-wallet');
    exit();
}
?>