<?php
/**
 * verify_va_transfer.php
 * Checks if a DVA bank transfer has been received and recorded.
 *
 * Primary path: dva_webhook.php processes charge.success and marks the pending
 * payment as processed. This endpoint just checks the DB.
 *
 * Fallback path: If the webhook hasn't fired yet, polls Paystack API directly,
 * records the payment, and marks the pending record as processed.
 */

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    exit;
}

header('Content-Type: application/json');

set_exception_handler(function ($e) {
    if (!headers_sent()) header('Content-Type: application/json');
    echo json_encode(['status' => 'error', 'message' => 'Server error: ' . $e->getMessage()]);
    exit;
});

$transferRef  = trim($_POST['transfer_reference'] ?? '');
$tabSessionID = trim($_POST['tab_id'] ?? '');

if (empty($transferRef)) {
    echo json_encode(['status' => 'expired', 'message' => 'Invalid or expired reference. Please refresh the page.']);
    exit;
}

require_once 'vendor/autoload.php';
include('includes/dbconnection.php');

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
$paystackSecretKey = $_ENV['PAYSTACK_SECRET_KEY'];

// Look up pending payment
$stmt = $con->prepare(
    "SELECT * FROM dva_pending_payments WHERE payment_reference = ? LIMIT 1"
);
$stmt->bind_param('s', $transferRef);
$stmt->execute();
$pendingRow = $stmt->get_result()->fetch_assoc();
$stmt->close();

if (!$pendingRow) {
    echo json_encode(['status' => 'expired', 'message' => 'Reference not found. Please refresh the page to start again.']);
    exit;
}

// Check expiry
if (new DateTime() > new DateTime($pendingRow['expires_at'])) {
    echo json_encode(['status' => 'expired', 'message' => 'Your transfer reference has expired. Please refresh the page to get a new one.']);
    exit;
}

$expectedAmount = floatval($pendingRow['amount']);
$sourcePage     = $pendingRow['source_page'];

// Start correct session
$entrancePages = ['confirmpayen', 'confirmpaylesson', 'confirmpayen2'];
$studentPages  = ['confirmpaynd', 'confirmpaynb'];

if (in_array($sourcePage, $entrancePages)) {
    if (empty($tabSessionID)) {
        http_response_code(403);
        echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
        exit;
    }
    session_write_close();
    session_id($tabSessionID);
    session_name('guest_portal_' . $tabSessionID);
    session_start();
} elseif (in_array($sourcePage, $studentPages)) {
    ini_set('session.gc_maxlifetime', 7200);
    ini_set('session.cookie_lifetime', 7200);
    session_name('student_portal');
    session_start();
    if (empty($tabSessionID)) {
        $tabSessionID = $_SESSION['current_tab_id'] ?? '';
    }
    if (empty($tabSessionID) || !isset($_SESSION['tabs'][$tabSessionID])) {
        http_response_code(403);
        echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
        exit;
    }
    $studentSession = $_SESSION['tabs'][$tabSessionID];
    $_SESSION['student_id'] = $studentSession['student_id'];
} else {
    http_response_code(403);
    echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
    exit;
}

// -----------------------------------------------------------------------
// PRIMARY: Check if dva_webhook.php already processed this payment
// -----------------------------------------------------------------------
$processedStmt = $con->prepare(
    "SELECT p.reference, p.amount
     FROM dva_pending_payments dp
     JOIN payments p ON p.reference = dp.paystack_reference
     WHERE dp.id = ? AND dp.processed = 1
     LIMIT 1"
);
$processedStmt->bind_param('i', $pendingRow['id']);
$processedStmt->execute();
$processedPayment = $processedStmt->get_result()->fetch_assoc();
$processedStmt->close();

if ($processedPayment) {
    // Webhook already handled it
    $paystackRef    = $processedPayment['reference'];
    $receivedAmount = floatval($processedPayment['amount']);
} else {
    // -----------------------------------------------------------------------
    // FALLBACK: Webhook hasn't fired yet — poll Paystack API directly
    // -----------------------------------------------------------------------
    // Use the specific virtual account for this payment type
    $paymentType = $pendingRow['payment_type'] ?? 'general';
    $dvaStmt = $con->prepare(
        "SELECT paystack_customer_id, paystack_dva_id FROM school_virtual_accounts WHERE payment_type = ? AND is_active = 1 LIMIT 1"
    );
    $dvaStmt->bind_param('s', $paymentType);
    $dvaStmt->execute();
    $dvaAccount = $dvaStmt->get_result()->fetch_assoc();
    $dvaStmt->close();

    if (!$dvaAccount) {
        echo json_encode(['status' => 'error', 'message' => 'No active virtual account configured.']);
        exit;
    }

    $customerId = $dvaAccount['paystack_customer_id'];
    $dvaId      = $dvaAccount['paystack_dva_id'];
    $expectedKobo = intval(round($expectedAmount * 100));
    $matchedTx    = null;

    // Strategy 1: Query transactions filtered by customer code
    $fromTs = urlencode(date('c', strtotime($pendingRow['created_at'])));
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,
        "https://api.paystack.co/transaction?customer={$customerId}&from={$fromTs}&perPage=50"
    );
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "Authorization: Bearer $paystackSecretKey",
        "Content-Type: application/json"
    ]);
    $response = curl_exec($ch);
    curl_close($ch);

    if ($response) {
        $data1 = json_decode($response, true);
        foreach ($data1['data'] ?? [] as $tx) {
            if (($tx['status'] ?? '') === 'success' && intval($tx['amount'] ?? 0) === $expectedKobo) {
                $matchedTx = $tx;
                break;
            }
        }
    }

    // Strategy 2: Query without date filter (broader)
    if (!$matchedTx) {
        $ch2 = curl_init();
        curl_setopt($ch2, CURLOPT_URL,
            "https://api.paystack.co/transaction?customer={$customerId}&perPage=50"
        );
        curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch2, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $paystackSecretKey",
            "Content-Type: application/json"
        ]);
        $response2 = curl_exec($ch2);
        curl_close($ch2);

        if ($response2) {
            $data2 = json_decode($response2, true);
            foreach ($data2['data'] ?? [] as $tx) {
                if (($tx['status'] ?? '') === 'success' && intval($tx['amount'] ?? 0) === $expectedKobo) {
                    $matchedTx = $tx;
                    break;
                }
            }
        }
    }

    // Strategy 3: Query all recent transactions (no customer filter) — last resort
    if (!$matchedTx) {
        $ch3 = curl_init();
        curl_setopt($ch3, CURLOPT_URL,
            "https://api.paystack.co/transaction?from={$fromTs}&perPage=100"
        );
        curl_setopt($ch3, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch3, CURLOPT_HTTPHEADER, [
            "Authorization: Bearer $paystackSecretKey",
            "Content-Type: application/json"
        ]);
        $response3 = curl_exec($ch3);
        curl_close($ch3);

        if ($response3) {
            $data3 = json_decode($response3, true);
            foreach ($data3['data'] ?? [] as $tx) {
                if (($tx['status'] ?? '') === 'success'
                    && intval($tx['amount'] ?? 0) === $expectedKobo
                    && ($tx['channel'] ?? '') === 'dedicated_nuban') {
                    $matchedTx = $tx;
                    break;
                }
            }
        }
    }

    error_log("DVA Verify fallback: paymentType={$paymentType}, customerId={$customerId}, expectedKobo={$expectedKobo}, found=" . ($matchedTx ? 'YES ref='.$matchedTx['reference'] : 'NO'));

    if (!$matchedTx) {
        echo json_encode([
            'status'  => 'not_received',
            'message' => 'Transfer not received yet. Please ensure you transferred the exact amount of ₦' . number_format($expectedAmount, 2) . ' and try again.',
        ]);
        exit;
    }

    $paystackRef    = $matchedTx['reference'];
    $receivedAmount = $matchedTx['amount'] / 100;

    // Record payment if not already done
    $dupCheck = $con->prepare("SELECT id FROM payments WHERE reference = ? LIMIT 1");
    $dupCheck->bind_param('s', $paystackRef);
    $dupCheck->execute();
    $dupRow = $dupCheck->get_result()->fetch_assoc();
    $dupCheck->close();

    if (!$dupRow) {
        $insertStmt = $con->prepare(
            "INSERT INTO payments
             (student_id, studentno, studentName, email, reference, amount, status,
              fee_type, payment_date, payment_method, term_id, session_id)
             VALUES (?, ?, ?, ?, ?, ?, 'approved', ?, NOW(), 'Bank Transfer', ?, ?)"
        );
        $insertStmt->bind_param(
            'sssssdsss',
            $pendingRow['student_id'], $pendingRow['studentno'], $pendingRow['studentName'],
            $pendingRow['email'], $paystackRef, $receivedAmount,
            $pendingRow['fee_type'], $pendingRow['term_id'], $pendingRow['session_id']
        );
        if (!$insertStmt->execute()) {
            $insertStmt->close();
            echo json_encode(['status' => 'error', 'message' => 'Payment record could not be saved.']);
            exit;
        }
        $insertStmt->close();
    }

    // Mark pending as processed
    $markStmt = $con->prepare(
        "UPDATE dva_pending_payments SET processed = 1, paystack_reference = ? WHERE id = ?"
    );
    $markStmt->bind_param('si', $paystackRef, $pendingRow['id']);
    $markStmt->execute();
    $markStmt->close();
}

// -----------------------------------------------------------------------
// Set session and return redirect URL
// -----------------------------------------------------------------------
$_SESSION['payment_details'] = [
    'transaction_id' => $paystackRef,
    'amount'         => $receivedAmount,
    'email'          => $pendingRow['email'],
    'payment_method' => 'Bank Transfer',
    'status'         => 'approved',
    'student_no'     => $pendingRow['studentno'],
    'student_name'   => $pendingRow['studentName'],
    'fee_type'       => $pendingRow['fee_type'],
    'tab_id'         => $tabSessionID,
    'term'           => $pendingRow['term_id'],
    'session'        => $pendingRow['session_id'],
];

$redirectUrl = in_array($sourcePage, $entrancePages)
    ? "confirmpaymententrance.php?tab_id={$tabSessionID}"
    : "confirmpayment.php?tab_id={$tabSessionID}";

echo json_encode(['status' => 'success', 'redirect_url' => $redirectUrl]);
