<?php
// api/place_order.php
//
// Receives an order from the customer menu. Status of the resulting
// row depends on the chosen payment_method:
//
//   cash, counter   → status='new', payment_status='not_required'
//                     (chime + email fire immediately)
//   knet_card       → status='pending_payment', payment_status='pending'
//                     We call MyFatoorah, return PaymentURL to menu,
//                     menu redirects customer to MF's hosted page.
//                     api/payment_callback.php finalizes after MF
//                     posts back with paymentId.
//   (empty)         → legacy WhatsApp flow: status='pending_whatsapp'
//                     Allowed only when admin's order_placement_mode
//                     setting permits WhatsApp.

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

header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json; charset=utf-8');

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    json_out(['error' => 'POST required'], 405);
}

$body = json_decode(file_get_contents('php://input'), true) ?? [];

$customerName        = trim($body['customer_name']  ?? '');
$customerPhone       = trim($body['customer_phone'] ?? '');
$customerCountryCode = trim($body['customer_country_code'] ?? '');  // "965" no plus
$customerPhoneLocal  = trim($body['customer_phone_local']  ?? '');  // "50123456"
$customerNotes       = trim($body['customer_notes'] ?? '');
$language      = $body['language'] ?? 'en';
$paymentMethod = $body['payment_method'] ?? '';   // cash | knet_card | counter | (empty)
$items         = $body['items'] ?? [];

// Multi-branch fields (Brand B). All optional — a single_location
// install simply never sends them, and they stay null on the order.
$branchId      = isset($body['branch_id']) && $body['branch_id'] !== ''
                 ? intval($body['branch_id']) : null;
$orderMode     = $body['order_mode'] ?? '';
if (!in_array($orderMode, ['delivery', 'pickup', 'dinein'], true)) {
    $orderMode = null;
}
// Table number only meaningful for dine-in; ignored otherwise.
$tableNumber   = ($orderMode === 'dinein')
                 ? trim($body['table_number'] ?? '')
                 : '';
if ($tableNumber === '') $tableNumber = null;

if ($customerName === '' || $customerPhone === '') {
    json_out(['error' => 'Name and phone are required'], 422);
}
if (!is_array($items) || count($items) === 0) {
    json_out(['error' => 'No items in order'], 422);
}
if (!in_array($language, ['en', 'ar'], true)) $language = 'en';

$customerPhone = normalize_phone($customerPhone);

// Pull all relevant settings in one query.
$settings = db()->query("SELECT key_name, value FROM settings WHERE key_name IN
    ('order_prefix', 'order_start_number', 'currency_code',
     'order_placement_mode',
     'payment_cash_enabled', 'payment_card_enabled', 'payment_counter_enabled')")
    ->fetchAll(PDO::FETCH_KEY_PAIR);

$mode = $settings['order_placement_mode'] ?? 'both';

// Validate the requested method against admin's enabled flags.
// An attacker could POST a method even when admin disabled it,
// so we re-check server-side rather than trusting the menu UI.
$valid_methods = [];
if (($settings['payment_cash_enabled']    ?? '0') === '1') $valid_methods[] = 'cash';
if (($settings['payment_card_enabled']    ?? '0') === '1') $valid_methods[] = 'knet_card';
if (($settings['payment_counter_enabled'] ?? '0') === '1') $valid_methods[] = 'counter';

if ($paymentMethod === '') {
    // Empty method = legacy WhatsApp. Only allowed when mode permits.
    if ($mode === 'payment_only') {
        json_out(['error' => 'A payment method is required'], 422);
    }
    $orderStatus   = 'pending_whatsapp';
    $paymentStatus = 'not_required';
} elseif (!in_array($paymentMethod, $valid_methods, true)) {
    json_out(['error' => 'Selected payment method is not enabled'], 422);
} else {
    if ($paymentMethod === 'knet_card') {
        $orderStatus   = 'pending_payment';
        $paymentStatus = 'pending';
    } else {
        $orderStatus   = 'new';        // cash / counter — visible to staff right away
        $paymentStatus = 'not_required';
    }
}

try {
    $pdo = db();
    $pdo->beginTransaction();

    $prefix   = $settings['order_prefix']        ?? 'ORD-';
    $startNum = intval($settings['order_start_number'] ?? 1001);
    $currency = $settings['currency_code']       ?? 'KD';

    $lastRow = $pdo->query("SELECT order_number FROM orders ORDER BY id DESC LIMIT 1")->fetch();
    if ($lastRow && preg_match('/(\d+)$/', $lastRow['order_number'], $m)) {
        $nextNum = intval($m[1]) + 1;
    } else {
        $nextNum = $startNum;
    }
    $orderNumber = $prefix . $nextNum;

    $total = 0;
    foreach ($items as $it) $total += floatval($it['subtotal'] ?? 0);

    $stmt = $pdo->prepare("
        INSERT INTO orders
            (order_number, customer_name, customer_phone, customer_notes,
             language, total, currency, items_json, status,
             payment_method, payment_status,
             branch_id, order_mode, order_table_number)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    $stmt->execute([
        $orderNumber,
        substr($customerName, 0, 200),
        substr($customerPhone, 0, 50),
        $customerNotes === '' ? null : substr($customerNotes, 0, 1000),
        $language,
        $total,
        $currency,
        json_encode($items, JSON_UNESCAPED_UNICODE),
        $orderStatus,
        $paymentMethod !== '' ? $paymentMethod : null,
        $paymentStatus,
        $branchId,
        $orderMode,
        $tableNumber,
    ]);
    $orderId = $pdo->lastInsertId();

    $insertItem = $pdo->prepare("
        INSERT INTO order_items
            (order_id, item_id, name_snapshot, name_ar_snapshot,
             size_label, size_label_ar, extras_json,
             quantity, unit_price, subtotal)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    foreach ($items as $it) {
        $insertItem->execute([
            $orderId,
            intval($it['item_id'] ?? 0) ?: null,
            substr(trim($it['name'] ?? ''), 0, 200),
            isset($it['name_ar']) ? substr(trim($it['name_ar']), 0, 200) : null,
            isset($it['size_label']) ? substr(trim($it['size_label']), 0, 100) : null,
            isset($it['size_label_ar']) ? substr(trim($it['size_label_ar']), 0, 100) : null,
            isset($it['extras']) ? json_encode($it['extras'], JSON_UNESCAPED_UNICODE) : null,
            max(1, intval($it['quantity'] ?? 1)),
            floatval($it['unit_price'] ?? 0),
            floatval($it['subtotal'] ?? 0),
        ]);
    }

    $pdo->commit();

} catch (Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack();
    json_out(['error' => 'Could not save order: ' . $e->getMessage()], 500);
}

// ── Branch on payment method for the response ────────────────

if ($paymentMethod === 'knet_card') {
    // Build MyFatoorah callback URL — include our order id as a
    // query param so the callback can find the right row even if
    // MF doesn't echo our reference back perfectly.
    $callbackUrl = SITE_URL . '/api/payment_callback.php?order=' . urlencode((string)$orderId);

    // "CARD" lets MyFatoorah's hosted page show all enabled card
    // methods (KNET, Visa, Mada, Apple Pay if enabled) so the
    // customer picks on their side. To force ONLY KNET, change
    // this to 'KNET'.
    // Pass 'ALL_GATEWAYS' to route through MyFatoorah's SendPayment
    // endpoint, which returns an InvoiceURL that shows ALL gateways
    // enabled in your portal (KNET, Visa, Mastercard, Mada, Apple
    // Pay, etc.) on the hosted page. The customer picks there.
    //
    // To force one gateway, replace with 'KNET' or 'CARD' — those
    // route through /v3/payments and skip the gateway picker.
    $mf = mf_create_payment('ALL_GATEWAYS', floatval($total), $callbackUrl, [
        'customer_name'           => $customerName,
        'customer_mobile'         => $customerPhone,        // combined; legacy fallback
        'customer_country_code'   => $customerCountryCode,  // preferred path
        'customer_phone_local'    => $customerPhoneLocal,
        'order_number'            => $orderNumber,
    ]);

    if (!$mf['ok']) {
        // Order is in DB but gateway rejected — mark it failed so
        // it doesn't sit in "pending" forever, and tell the customer.
        db()->prepare("UPDATE orders SET status='payment_failed', payment_status='failed' WHERE id=?")
            ->execute([$orderId]);
        json_out([
            'error'        => 'Payment gateway error: ' . ($mf['error'] ?? 'unknown'),
            'order_number' => $orderNumber,
        ], 502);
    }

    $paymentUrl = $mf['data']['PaymentURL'] ?? '';
    $invoiceId  = $mf['data']['InvoiceId']  ?? '';
    db()->prepare("UPDATE orders SET mf_invoice_id=?, payment_url=? WHERE id=?")
        ->execute([$invoiceId, $paymentUrl, $orderId]);

    json_out([
        'ok'           => true,
        'order_number' => $orderNumber,
        'total'        => $total,
        'currency'     => $currency,
        'payment_url'  => $paymentUrl,   // menu redirects browser here
    ]);
}

// Cash / counter / WhatsApp legacy
// For cash + counter, fire the confirmation email since these are
// effectively confirmed and staff sees them immediately.
if (in_array($paymentMethod, ['cash', 'counter'], true)) {
    require_once __DIR__ . '/../mailer.php';
    try {
        send_order_email($orderNumber, $customerName, $customerPhone,
                         $customerNotes, $language, $items,
                         floatval($total), $currency);
    } catch (Throwable $e) {
        error_log('Order email failed: ' . $e->getMessage());
    }
}

json_out([
    'ok'           => true,
    'order_number' => $orderNumber,
    'total'        => $total,
    'currency'     => $currency,
]);


// ── Phone normalization (Kuwait-aware) ───────────────────────
function normalize_phone(string $raw): string {
    $clean = preg_replace('/[^\d+]/', '', $raw);
    if ($clean === '' || $clean === '+') return $raw;
    if (str_starts_with($clean, '+')) return $clean;
    if (str_starts_with($clean, '00')) return '+' . substr($clean, 2);
    if (str_starts_with($clean, '965') && strlen($clean) >= 11) return '+' . $clean;
    if (str_starts_with($clean, '0')) return '+965' . substr($clean, 1);
    if (strlen($clean) === 8) return '+965' . $clean;
    return '+965' . $clean;
}
