<?php
// api/payment_callback.php
//
// MyFatoorah redirects the customer's browser here AFTER the
// payment attempt. The URL looks like:
//   /api/payment_callback.php?order=42&paymentId=07076389491322460173
//
// We:
//   1. Look up the order by id (the ?order= we added when creating the session)
//   2. Call MyFatoorah's GetPaymentStatus to verify the actual outcome
//      — never trust the redirect URL alone; anyone can craft one.
//   3. Update the order to "new" + paid (success) or "payment_failed" (failure)
//   4. On success: send confirmation email + redirect to /payment_success.html
//   5. On failure: redirect to /payment_failed.html with the order number
//
// This is a customer-facing browser redirect endpoint, not JSON.

require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../myfatoorah.php';

// ── Find the order ────────────────────────────────────────────
$orderId   = intval($_GET['order'] ?? 0);
$paymentId = trim($_GET['paymentId'] ?? '');

if (!$orderId) {
    redirect_to_failure(null, 'Missing order reference');
}

$pdo = db();
$row = $pdo->prepare('SELECT * FROM orders WHERE id = ?');
$row->execute([$orderId]);
$order = $row->fetch();
if (!$order) {
    redirect_to_failure(null, 'Order not found');
}

// ── Idempotency: if already finalized, don't re-process ──────
// MyFatoorah might redirect twice (e.g. customer clicks back).
// We treat any status != pending_payment as final and just
// redirect to the right page based on current state.
if ($order['status'] !== 'pending_payment') {
    if ($order['payment_status'] === 'paid') {
        redirect_to_success($order['order_number']);
    } else {
        redirect_to_failure($order['order_number'], 'Payment was not completed');
    }
}

// ── Verify with MyFatoorah ───────────────────────────────────
if ($paymentId === '') {
    // No paymentId in callback URL — likely a "back" or cancel.
    // Mark as failed and send to failure page.
    finalize_failed($orderId, 'No payment ID returned from gateway');
    redirect_to_failure($order['order_number'], 'Payment was cancelled');
}

$status = mf_get_payment_status($paymentId);
if (!$status['ok']) {
    error_log("MF status check failed for order $orderId: " . ($status['error'] ?? ''));
    finalize_failed($orderId, 'Could not verify payment with gateway');
    redirect_to_failure($order['order_number'], 'Could not verify payment status');
}

// MyFatoorah's response: Data.Invoice.Status + Data.Transaction.Status.
// Both should indicate success for us to mark paid.
$invoiceStatus = strtoupper($status['data']['Invoice']['Status']     ?? '');
$txnStatus     = strtoupper($status['data']['Transaction']['Status'] ?? '');
$mfPaymentId   = $status['data']['Transaction']['PaymentId'] ?? $paymentId;

if ($invoiceStatus === 'PAID' && $txnStatus === 'SUCCESS') {
    finalize_paid($orderId, $mfPaymentId, $order);
    redirect_to_success($order['order_number']);
}

// Anything else — declined, expired, failed, etc.
$reason = $status['data']['Transaction']['Error']['Message'] ?? '';
if ($reason === '') $reason = "Payment status: $invoiceStatus / $txnStatus";
finalize_failed($orderId, $reason);
redirect_to_failure($order['order_number'], $reason);


// ── Helpers ───────────────────────────────────────────────────

/**
 * Mark order paid + new, fire confirmation email, log the transaction id.
 */
function finalize_paid(int $orderId, string $mfPaymentId, array $order): void
{
    db()->prepare("UPDATE orders
        SET status='new', payment_status='paid', mf_payment_id=?
        WHERE id=?")
        ->execute([$mfPaymentId, $orderId]);

    // Fire the confirmation email. Wrapped in try/catch — email
    // failures shouldn't break the customer's redirect to success.
    require_once __DIR__ . '/../mailer.php';
    try {
        $items = json_decode($order['items_json'] ?? '[]', true) ?: [];
        send_order_email(
            $order['order_number'],
            $order['customer_name'],
            $order['customer_phone'],
            $order['customer_notes'] ?? '',
            $order['language'] ?? 'en',
            $items,
            floatval($order['total']),
            $order['currency'] ?? 'KD'
        );
    } catch (Throwable $e) {
        error_log('Order email failed after payment: ' . $e->getMessage());
    }
}

function finalize_failed(int $orderId, string $reason): void
{
    db()->prepare("UPDATE orders
        SET status='payment_failed', payment_status='failed'
        WHERE id=? AND status='pending_payment'")
        ->execute([$orderId]);
    error_log("Payment failed for order $orderId: $reason");
}

function redirect_to_success(string $orderNumber): never
{
    header('Location: ' . SITE_URL . '/payment_success.html?order=' . urlencode($orderNumber));
    exit;
}

function redirect_to_failure(?string $orderNumber, string $reason): never
{
    $url = SITE_URL . '/payment_failed.html'
         . '?reason=' . urlencode($reason)
         . ($orderNumber ? '&order=' . urlencode($orderNumber) : '');
    header('Location: ' . $url);
    exit;
}
