<?php
/**
 * Paystack Redirect Handler
 * SECURITY: Verifies payment signatures and validates payment intent before redirecting to Paystack
 */

session_start();
require_once 'config.php';
require_once 'config_paystack.php';
require_once 'app/classes/MinimumTopupManager.php';

$reference = isset($_GET['ref']) ? trim($_GET['ref']) : '';
$amountKobo = isset($_GET['amount']) ? intval($_GET['amount']) : 0; // minor units (pesewas) - total including charge
$email = isset($_GET['email']) ? trim($_GET['email']) : '';
$signature = isset($_GET['sig']) ? trim($_GET['sig']) : '';
$storeId = isset($_GET['store_id']) ? intval($_GET['store_id']) : null; // Store ID for sub-agent top-ups

// Get base amount and charge breakdown
$baseAmount = isset($_GET['base_amount']) ? floatval($_GET['base_amount']) : 0;
$chargeAmount = isset($_GET['charge_amount']) ? floatval($_GET['charge_amount']) : 0;
$chargeType = isset($_GET['charge_type']) ? trim($_GET['charge_type']) : 'none';

// SECURITY: Basic validation
if ($reference === '' || $amountKobo <= 0 || $email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
    error_log("SECURITY: Invalid payment parameters - Reference: $reference, IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
    http_response_code(400);
    echo 'Invalid payment initialization parameters';
    exit;
}

// SECURITY: Verify signature to prevent URL manipulation
if (!empty($signature)) {
    // Get Paystack config - use store-specific if store_id is provided (for sub-agents)
    $paystackConfig = getPaystackConfig(true, $storeId);
    $paystackSecretKey = $paystackConfig['secret_key'];
    
    $expectedSignature = hash_hmac('sha256', $reference . '|' . $amountKobo . '|' . $email . '|' . $baseAmount . '|' . $chargeAmount, $paystackSecretKey);
    
    if (!hash_equals($expectedSignature, $signature)) {
        error_log("SECURITY: Invalid payment signature - Reference: $reference, IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        http_response_code(403);
        echo 'Invalid payment signature. Payment parameters may have been tampered with.';
        exit;
    }
    
    // SECURITY: Verify payment intent exists in database and matches parameters
    $verifyStmt = $conn->prepare("
        SELECT op.id, op.user_id, op.total_amount, op.payment_status, a.email, a.role, a.is_store_owner, a.store_id
        FROM orders_payments op
        JOIN agents a ON op.user_id = a.id
        WHERE op.payment_reference = ? AND op.payment_status = 'pending'
    ");
    $verifyStmt->bind_param("s", $reference);
    $verifyStmt->execute();
    $verifyResult = $verifyStmt->get_result();
    $paymentIntent = $verifyResult->fetch_assoc();
    $verifyStmt->close();
    
    if (!$paymentIntent) {
        error_log("SECURITY: Payment intent not found - Reference: $reference, IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        http_response_code(404);
        echo 'Payment intent not found or already processed.';
        exit;
    }
    
    // SECURITY: Verify user is either store owner OR sub-agent
    $isStoreOwner = ($paymentIntent['role'] === 'store_owner' || $paymentIntent['is_store_owner'] == 1);
    $isSubAgent = (!$isStoreOwner && !empty($paymentIntent['store_id']));
    
    if (!$isStoreOwner && !$isSubAgent) {
        error_log("SECURITY: Unauthorized payment redirect - User ID: " . $paymentIntent['user_id'] . ", Reference: $reference, IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        http_response_code(403);
        echo 'Unauthorized payment request.';
        exit;
    }
    
    // SECURITY: If sub-agent, verify store_id matches
    if ($isSubAgent && $storeId && $paymentIntent['store_id'] != $storeId) {
        error_log("SECURITY: Store ID mismatch - Reference: $reference, Expected: " . $paymentIntent['store_id'] . ", Got: $storeId, IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        http_response_code(403);
        echo 'Store ID mismatch detected.';
        exit;
    }
    
    // SECURITY: Verify email matches
    if ($paymentIntent['email'] !== $email) {
        error_log("SECURITY: Email mismatch - Reference: $reference, Expected: " . $paymentIntent['email'] . ", Got: $email, IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        http_response_code(403);
        echo 'Email mismatch detected.';
        exit;
    }
    
    // SECURITY: Verify amount matches (allow small floating point differences)
    $expectedAmount = floatval($paymentIntent['total_amount']);
    if (abs($baseAmount - $expectedAmount) > 0.01) {
        error_log("SECURITY: Amount mismatch - Reference: $reference, Expected: $expectedAmount, Got: $baseAmount, IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        http_response_code(403);
        echo 'Amount mismatch detected.';
        exit;
    }
    
    // SECURITY: Verify user is logged in and matches payment intent
    if (!isset($_SESSION['user_id']) || $_SESSION['user_id'] != $paymentIntent['user_id']) {
        error_log("SECURITY: User session mismatch - Reference: $reference, Expected User: " . $paymentIntent['user_id'] . ", Session User: " . ($_SESSION['user_id'] ?? 'none') . ", IP: " . ($_SERVER['REMOTE_ADDR'] ?? 'unknown'));
        http_response_code(403);
        echo 'Session mismatch detected.';
        exit;
    }
    
    // If store_id wasn't provided but user is sub-agent, get it from payment intent
    if ($isSubAgent && !$storeId) {
        $storeId = $paymentIntent['store_id'];
    }
}

// Paystack requires a minimum amount in minor units (typically >= 100)
if ($amountKobo < 100) {
    http_response_code(400);
    echo 'Minimum payment amount is 1.00 GHS';
    exit;
}

// Check minimum top-up configuration
$minimumTopupManager = new MinimumTopupManager($conn);
$amountGHS = $amountKobo / 100; // Convert to GHS

$validation = $minimumTopupManager->validateTopupAmount($amountGHS);
if (!$validation['valid']) {
    http_response_code(400);
    echo $validation['message'];
    exit;
}

$callbackBase = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
$callbackPath = rtrim(str_replace('\\', '/', dirname($_SERVER['PHP_SELF'])), '/');
$callbackUrl = $callbackBase . ($callbackPath ? $callbackPath : '') . '/paystack_callback.php';

// Store payment breakdown in session as backup (in case metadata doesn't come through)
$_SESSION['paystack_topup_' . $reference] = [
    'base_amount' => $baseAmount,
    'charge_amount' => $chargeAmount,
    'charge_type' => $chargeType,
    'total_amount' => $amountKobo / 100,
    'timestamp' => time()
];

// Prepare metadata with payment breakdown
$metadata = [
    'base_amount' => $baseAmount,
    'charge_amount' => $chargeAmount,
    'charge_type' => $chargeType
];

$payload = [
    'email' => $email,
    'amount' => $amountKobo,
    'reference' => $reference,
    'currency' => 'GHS',
    'callback_url' => $callbackUrl,
    'metadata' => $metadata
];

// Get Paystack credentials - use store-specific if store_id is provided (for sub-agents)
$paystackConfig = getPaystackConfig(true, $storeId);
$paystackSecretKey = $paystackConfig['secret_key'];
$paystackBaseUrl = $paystackConfig['base_url'];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $paystackBaseUrl . '/transaction/initialize');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $paystackSecretKey,
    'Content-Type: application/json'
]);
$response = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response === false) {
    $err = curl_error($ch);
    error_log('Paystack init error (first attempt): ' . $err);
    // Retry with relaxed SSL (DEV ONLY fallback)
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    $response = curl_exec($ch);
    $http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
}
if ($response === false) {
    $err = curl_error($ch);
    curl_close($ch);
    error_log('Paystack init error (final): ' . $err);
    http_response_code(502);
    echo 'Payment service unavailable';
    exit;
}
$data = json_decode($response, true);
curl_close($ch);

if ($http !== 200 || !($data['status'] ?? false)) {
    error_log('Paystack init failed: ' . $response);
    http_response_code(502);
    echo 'Failed to initialize payment';
    exit;
}

$authUrl = $data['data']['authorization_url'] ?? '';
if (!$authUrl) {
    http_response_code(502);
    echo 'Invalid payment response';
    exit;
}

header('Location: ' . $authUrl);
exit;




