<?php
// api/pay.php

// Always return JSON — catch fatal errors before they output HTML
register_shutdown_function(function () {
    $err = error_get_last();
    if ($err && in_array($err['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        if (!headers_sent()) header('Content-Type: application/json');
        echo json_encode(['success' => false, 'message' => 'Server error: ' . $err['message']]);
    }
});

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Accept');

// Handle CORS preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200); exit;
}

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

// ---- Load config and helper ----
$baseDir = dirname(__DIR__);
require_once $baseDir . '/config.php';
require_once $baseDir . '/includes/kindamba.php';

$input = json_decode(file_get_contents('php://input'), true);
if (empty($input) && !empty($_POST)) {
    $input = $_POST;
}

if (!is_array($input)) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Invalid request body.']);
    exit;
}

$phone   = trim($input['phone']   ?? '');
$amount  = (int) ($input['amount']  ?? 0);
$videoID = trim($input['videoID'] ?? $input['video_id'] ?? '');
$name    = trim($input['name']    ?? 'Guest Customer');
$email   = trim($input['email']   ?? 'guest@kindamba.site');

// ---- Validate ----
if (!preg_match('/^0[0-9]{9}$/', $phone)) {
    http_response_code(422);
    echo json_encode(['success' => false, 'message' => 'Invalid phone number. Must be 10 digits starting with 0.']);
    exit;
}
if ($amount <= 0) {
    http_response_code(422);
    echo json_encode(['success' => false, 'message' => 'Amount must be greater than 0.']);
    exit;
}
if (empty($videoID)) {
    http_response_code(422);
    echo json_encode(['success' => false, 'message' => 'Video ID is required.']);
    exit;
}

// ---- Determine which API Key and Verify Price ----
$publicKey = !empty($input['token']) ? $input['token'] : null;
$userRedirectUrl = SITE_URL;

require_once $baseDir . '/includes/db.php';
try {
    // Also fetch the video price to verify the amount
    $stmt = $pdo->prepare("SELECT u.api_key, u.redirect_url, u.webhook_token, v.price FROM users u JOIN videos v ON u.id = v.user_id WHERE v.id = ? LIMIT 1");
    $stmt->execute([$videoID]);
    $owner = $stmt->fetch(PDO::FETCH_ASSOC);
    
    if (!$owner) {
        http_response_code(404);
        echo json_encode(['success' => false, 'message' => 'Video not found.']);
        exit;
    }

    // Security: Validate amount against DB price
    if ($amount !== (int)$owner['price']) {
        error_log("[KindambaPay] Security Alert: Price mismatch for Video ID $videoID. Requested: $amount, DB: " . $owner['price']);
        http_response_code(400);
        echo json_encode(['success' => false, 'message' => 'Invalid payment amount. Please refresh and try again.']);
        exit;
    }

    $webhookToken = '';
    $ownerKey = $owner['api_key'] ?? '';
    $webhookToken = $owner['webhook_token'] ?? '';
    if (!empty($owner['redirect_url'])) {
        $userRedirectUrl = $owner['redirect_url'];
    }

    if (!$publicKey) {
        if ($ownerKey && stripos($ownerKey, 'pk_') === 0) {
            $publicKey = $ownerKey;
        }
    }

    // Fallback if no specific owner token found
    if (empty($webhookToken)) {
        $adminStmt = $pdo->query("SELECT webhook_token FROM users WHERE id = 1 LIMIT 1");
        $webhookToken = $adminStmt->fetchColumn() ?: '';
    }
} catch (Exception $e) {
    error_log('[KindambaPay] DB Error fetching owner data: ' . $e->getMessage());
}

// Get absolute callback URL with security token
$callbackUrl = SITE_URL . '/webhook.php?token=' . urlencode($webhookToken);

$result = kindamba_initiate_payment($phone, $amount, $name, $email, 'VID-' . $videoID . '-' . time(), $callbackUrl, $publicKey);

if ($result['code'] < 200 || $result['code'] >= 300) {
    $msg = $result['data']['message'] ?? 'Kindamba Pay error (HTTP ' . $result['code'] . ').';
    error_log('[KindambaPay] HTTP ' . $result['code'] . ': ' . $msg);
    http_response_code(502);
    echo json_encode(['success' => false, 'message' => $msg]);
    exit;
}

$data = $result['data'];
// Kindamba Pay returns: { "success": true, "data": { "transaction_id": "...", "status": "pending", "message": "..." } }
$tranId = $data['data']['transaction_id'] ?? null;

if (empty($tranId)) {
    error_log('[KindambaPay] No transaction_id in response: ' . json_encode($data));
    http_response_code(502);
    echo json_encode(['success' => false, 'message' => 'Payment initiated but no transaction ID returned.']);
    exit;
}

// ---- Determine true initial status ----
$rawStatus = strtolower($data['data']['status'] ?? 'pending');
$initialStatus = 'pending';

if (in_array($rawStatus, ['completed', 'success', 'paid', 'successful'])) {
    $initialStatus = 'completed';
} elseif (in_array($rawStatus, ['failed', 'error', 'rejected'])) {
    $initialStatus = 'failed';
} elseif (in_array($rawStatus, ['inprogress', 'processing', 'initiated'])) {
    $initialStatus = 'pending';
}

// ---- Log transaction into DB ----
require_once $baseDir . '/includes/db.php';
try {
    $stmt = $pdo->prepare("INSERT IGNORE INTO transactions (tran_id, video_id, phone_number, amount, status, method) VALUES (?, ?, ?, ?, ?, 'Mobile Money')");
    $stmt->execute([$tranId, $videoID, $phone, $amount, $initialStatus]);
} catch (Exception $e) {
    error_log('[KindambaPay] Error inserting initial transaction: ' . $e->getMessage());
}

echo json_encode([
    'success'        => true,
    'transaction_id' => $tranId,
    'redirect_url'   => $userRedirectUrl,
    'message'        => 'STK push sent. Please check your phone.',
]);
