<?php
// ================================
// PESAPAL PAYMENT HANDLER (API 3.0)
// ================================

require_once '../config.php';
require_once '../includes/db.php';
require_once '../includes/functions.php';

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

$method = $_SERVER['REQUEST_METHOD'];

if ($method !== 'POST') {
    http_response_code(405);
    echo json_encode(['success' => false, 'message' => 'Method not allowed']);
    exit;
}

// Get PesaPal credentials
$consumer_key = getSetting('pesapal_consumer_key');
$consumer_secret = getSetting('pesapal_consumer_secret');
$mode = getSetting('pesapal_mode', 'sandbox');
$callback_url = getSetting('pesapal_callback_url');

// Parse request
$input = json_decode(file_get_contents('php://input'), true);
$phone = $input['phone'] ?? '';
$box_number = $input['box_number'] ?? '';

if (!$phone || !$box_number) {
    echo json_encode(['success' => false, 'message' => 'Missing phone or box_number']);
    exit;
}

// Get box details
$stmt = $pdo->prepare("SELECT id, amount, name FROM services WHERE box_number = ? AND active = 1");
$stmt->execute([$box_number]);
$box = $stmt->fetch();

if (!$box) {
    echo json_encode(['success' => false, 'message' => 'Box not found']);
    exit;
}

// ================================
// STEP 1: GET AUTH TOKEN
// ================================
$auth_token = getPesapalAuthToken($consumer_key, $consumer_secret, $mode);
if (!$auth_token) {
    echo json_encode(['success' => false, 'message' => 'Failed to authenticate with PesaPal']);
    exit;
}

// ================================
// STEP 2: REGISTER IPN (if not already registered)
// ================================
$ipn_id = getSetting('pesapal_ipn_id');
if (!$ipn_id) {
    $ipn_id = registerPesapalIPN($auth_token, $callback_url, $mode);
    if ($ipn_id) {
        updateSetting('pesapal_ipn_id', $ipn_id);
    }
}

if (!$ipn_id) {
    echo json_encode(['success' => false, 'message' => 'Failed to register IPN']);
    exit;
}

// ================================
// STEP 3: SUBMIT ORDER REQUEST
// ================================
$order_response = submitPesapalOrder($auth_token, $ipn_id, $phone, $box['amount'], $box['name'], $mode);

if (!$order_response || !isset($order_response->order_tracking_id)) {
    echo json_encode(['success' => false, 'message' => 'Failed to submit order']);
    exit;
}

// ================================
// SAVE TRANSACTION
// ================================
$merchant_reference = 'SHINDA-' . time() . '-' . $phone;

$stmt = $pdo->prepare("
    INSERT INTO transactions (phone, amount, order_tracking_id, merchant_reference, status)
    VALUES (?, ?, ?, ?, 'pending')
");
$stmt->execute([$phone, $box['amount'], $order_response->order_tracking_id, $merchant_reference]);

echo json_encode([
    'success' => true,
    'order_tracking_id' => $order_response->order_tracking_id,
    'merchant_reference' => $merchant_reference,
    'redirect_url' => $order_response->redirect_url ?? null,
    'amount' => $box['amount']
]);

// ================================
// PESAPAL API FUNCTIONS
// ================================

function getPesapalAuthToken($consumer_key, $consumer_secret, $mode) {
    $url = $mode === 'production'
        ? 'https://pay.pesapal.com/v3/api/Auth/RequestToken'
        : 'https://cybqa.pesapal.com/pesapalv3/api/Auth/RequestToken';

    $data = [
        'consumer_key' => $consumer_key,
        'consumer_secret' => $consumer_secret
    ];

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Accept: application/json'],
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15
    ]);

    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($http_code === 200) {
        $result = json_decode($response);
        return $result->token ?? null;
    }

    return null;
}

function registerPesapalIPN($token, $callback_url, $mode) {
    $url = $mode === 'production'
        ? 'https://pay.pesapal.com/v3/api/URLSetup/RegisterIPN'
        : 'https://cybqa.pesapal.com/pesapalv3/api/URLSetup/RegisterIPN';

    $data = [
        'url' => $callback_url,
        'ipn_notification_type' => 'GET'
    ];

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER => [
            "Authorization: Bearer $token",
            'Content-Type: application/json'
        ],
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15
    ]);

    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($http_code === 200) {
        $result = json_decode($response);
        return $result->ipn_id ?? null;
    }

    return null;
}

function submitPesapalOrder($token, $ipn_id, $phone, $amount, $description, $mode) {
    $url = $mode === 'production'
        ? 'https://pay.pesapal.com/v3/api/Transactions/SubmitOrderRequest'
        : 'https://cybqa.pesapal.com/pesapalv3/api/Transactions/SubmitOrderRequest';

    $orderData = [
        'id' => 'ORDER_' . time() . '_' . $phone,
        'currency' => 'KES',
        'amount' => floatval($amount),
        'description' => $description,
        'callback_url' => getSetting('pesapal_callback_url'),
        'notification_id' => $ipn_id,
        'billing_address' => [
            'email_address' => $phone . '@pesapal.ussd',
            'phone_number' => $phone,
            'first_name' => 'USSD User',
            'last_name' => substr($phone, -4)
        ]
    ];

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_HTTPHEADER => [
            "Authorization: Bearer $token",
            'Content-Type: application/json'
        ],
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($orderData),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 15
    ]);

    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($http_code === 200) {
        return json_decode($response);
    }

    return null;
}
?>