<?php
require_once __DIR__ . '/includes/config.php';
require_once __DIR__ . '/includes/database.php';

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

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    echo json_encode(['error' => 'Method Not Allowed']);
    exit;
}

// Read and decode JSON input
$input = json_decode(file_get_contents('php://input'), true);

// CSRF (token arrives via X-CSRF-Token header from register.php)
require_csrf(true, is_array($input) ? $input : null);

$razorpayPaymentId = $input['razorpay_payment_id'] ?? '';
$razorpayOrderId   = $input['razorpay_order_id'] ?? '';
$razorpaySignature = $input['razorpay_signature'] ?? '';

if (!$razorpayPaymentId || !$razorpayOrderId || !$razorpaySignature) {
    http_response_code(400);
    echo json_encode(['error' => 'Missing verification data.']);
    exit;
}

// 1. Verify signature cryptographically (constant-time compare)
$expectedSignature = hash_hmac('sha256', $razorpayOrderId . '|' . $razorpayPaymentId, RAZORPAY_KEY_SECRET);

if (!hash_equals($expectedSignature, (string)$razorpaySignature)) {
    http_response_code(400);
    echo json_encode(['error' => 'Payment signature verification failed. Transaction is invalid.']);
    exit;
}

// 2. Fetch the order from Razorpay — its notes/amount (set server-side in
//    create_order.php) are the source of truth. Never trust client-supplied
//    registration details or amounts.
$ch = curl_init('https://api.razorpay.com/v1/orders/' . rawurlencode($razorpayOrderId));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, RAZORPAY_KEY_ID . ':' . RAZORPAY_KEY_SECRET);
$orderResponse = curl_exec($ch);
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpStatusCode !== 200) {
    error_log("Razorpay Order Fetch Failed ($httpStatusCode): " . $orderResponse);
    http_response_code(500);
    echo json_encode(['error' => 'Could not confirm order with payment gateway. Please contact support with payment ID: ' . htmlspecialchars($razorpayPaymentId)]);
    exit;
}

$order = json_decode($orderResponse, true);
$notes = $order['notes'] ?? [];

$eventId      = $notes['eventId'] ?? '';
$fullName     = $notes['fullName'] ?? '';
$email        = $notes['email'] ?? '';
$mobileNumber = $notes['mobileNumber'] ?? '';
$city         = $notes['city'] ?? '';
$college      = $notes['college'] ?? '';
$paidAmount   = ((int)($order['amount'] ?? 0)) / 100; // paise → rupees

if (!$eventId || !$fullName || !$email || !$mobileNumber || !$city || !$college) {
    error_log("Razorpay order $razorpayOrderId has incomplete notes.");
    http_response_code(400);
    echo json_encode(['error' => 'Order is missing registration details. Please contact support with payment ID: ' . htmlspecialchars($razorpayPaymentId)]);
    exit;
}

$pdo = getDatabaseConnection();

try {
    // Start Transaction
    $pdo->beginTransaction();

    // 3. Event must exist and be published
    $evtStmt = $pdo->prepare("SELECT * FROM events WHERE id = ? AND status = 'PUBLISHED'");
    $evtStmt->execute([$eventId]);
    $event = $evtStmt->fetch(PDO::FETCH_ASSOC);

    if (!$event) {
        $pdo->rollBack();
        http_response_code(400);
        echo json_encode(['error' => 'Event not found or not open for registration.']);
        exit;
    }

    // 4. Idempotency: double submission of the same payment
    $checkStmt = $pdo->prepare("SELECT registrationId FROM registrations WHERE email = ? AND eventId = ?");
    $checkStmt->execute([$email, $eventId]);
    $existingRegId = $checkStmt->fetchColumn();

    if ($existingRegId) {
        $pdo->rollBack();
        echo json_encode([
            'status' => 'success',
            'registrationId' => $existingRegId
        ]);
        exit;
    }

    // 5. Generate unique Registration ID
    do {
        $regIdCode = strtoupper(substr($event['slug'], 0, 3)) . rand(10000, 99999);
        $checkExistStmt = $pdo->prepare("SELECT COUNT(*) FROM registrations WHERE registrationId = ?");
        $checkExistStmt->execute([$regIdCode]);
        $exists = $checkExistStmt->fetchColumn();
    } while ($exists > 0);

    // 6. Insert Registration
    $insertReg = $pdo->prepare("INSERT INTO registrations (id, registrationId, eventId, fullName, email, mobileNumber, college, city) VALUES (UUID(), ?, ?, ?, ?, ?, ?, ?)");
    $insertReg->execute([$regIdCode, $eventId, $fullName, $email, $mobileNumber, $college, $city]);

    // Fetch newly created registration UUID
    $regIdStmt = $pdo->prepare("SELECT id FROM registrations WHERE registrationId = ?");
    $regIdStmt->execute([$regIdCode]);
    $regRecord = $regIdStmt->fetch(PDO::FETCH_ASSOC);

    // 7. Insert Payment Record — amount is what Razorpay says was ordered
    $insertPay = $pdo->prepare("INSERT INTO payments (id, registrationId, amount, currency, razorpayOrderId, razorpayPaymentId, razorpaySignature, status) VALUES (UUID(), ?, ?, 'INR', ?, ?, ?, 'SUCCESSFUL')");
    $insertPay->execute([
        $regRecord['id'],
        $paidAmount,
        $razorpayOrderId,
        $razorpayPaymentId,
        $razorpaySignature
    ]);

    // Commit Transaction
    $pdo->commit();

    echo json_encode([
        'status' => 'success',
        'registrationId' => $regIdCode
    ]);
    exit;

} catch (Exception $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log("Payment Verification DB Exception: " . $e->getMessage());
    http_response_code(500);
    echo json_encode(['error' => 'Failed to save registration details. Please contact support with payment ID: ' . htmlspecialchars($razorpayPaymentId)]);
    exit;
}
