<?php
// ============================================================
//  MediCore — Online Orders API (staff side)
//  File: api/online-orders.php
//  Review queue for orders placed through the customer portal
//  (see api/customer-shop.php's api_place_order()). Approving an
//  order does NOT create a sale automatically — it only flips the
//  order to 'approved' so staff can be routed into Sale Entry
//  (sale/entry.php?online_order=<id>) with the items pre-filled,
//  where they can adjust quantities/discounts before saving as a
//  real sale. Once saved, sale/entry.php calls the `link_sale`
//  action here to record the resulting sale id on the order for
//  traceability (online_orders.converted_sale_id).
//  Accepts JSON POST, returns JSON.
// ============================================================
require_once '../includes/db.php';
require_once '../includes/auth.php';
require_once '../includes/audit.php';
require_once '../includes/customer_portal.php';
require_once '../includes/gateways.php';
require_login();
session_write_close(); // release session lock — prevents request queuing

ensure_customer_portal_schema();

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

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

try {
    match ($action) {
        'list'      => api_list($body),
        'detail'    => api_detail($body),
        'approve'   => api_approve($body),
        'reject'    => api_reject($body),
        'link_sale' => api_link_sale($body),
        default     => fail('Unknown action'),
    };
} catch (Throwable $e) {
    fail($e->getMessage());
}

// ── List ──────────────────────────────────────────────────────
function api_list(array $b): void {
    $status = trim($b['status'] ?? '');
    $where  = ['1=1'];
    $params = [];
    if ($status) { $where[] = 'status = ?'; $params[] = $status; }

    $rows = db_rows(
        "SELECT * FROM online_orders WHERE " . implode(' AND ', $where) . "
          ORDER BY created_at DESC",
        $params
    );
    ok(['data' => $rows]);
}

// ── Detail ────────────────────────────────────────────────────
function api_detail(array $b): void {
    $id = (int) ($b['id'] ?? 0);
    if (!$id) fail('Missing id');

    $order = db_row("SELECT * FROM online_orders WHERE id = ?", [$id]);
    if (!$order) fail('Order not found.');

    $items = db_rows("SELECT * FROM online_order_items WHERE online_order_id = ? ORDER BY id", [$id]);
    ok(['data' => $order, 'items' => $items]);
}

// ── Approve → mark approved only; NO sale is created here.
//    Staff finish the sale in Sale Entry (pre-filled from this
//    order), where they can adjust qty/discounts before saving.
function api_approve(array $b): void {
    if (!can_approve_online_order()) fail('Access denied. Admin or Manager role required.');

    $id = (int) ($b['id'] ?? 0);
    if (!$id) fail('Missing id');

    $order = db_row("SELECT * FROM online_orders WHERE id = ?", [$id]);
    if (!$order) fail('Order not found.');
    if ($order['status'] !== 'pending') fail('This order has already been reviewed.');

    $customer = db_row("SELECT * FROM customers WHERE id = ?", [$order['customer_id']]);

    db_run(
        "UPDATE online_orders
            SET status = 'approved', reviewed_by = ?, reviewed_at = NOW()
          WHERE id = ?",
        [current_user_id(), $id]
    );

    log_action('update', 'online_orders', $id,
        "Approved {$order['order_no']} — sent to Sale Entry for finalization");

    // Notify the customer — best-effort, never blocks approval.
    if ($customer) {
        notify_order_status($customer['phone'], $customer['email'] ?: null, $order['order_no'], 'approved');
    }

    ok([
        'msg' => 'Order approved. Continue in Sale Entry to finalize the sale.',
    ]);
}

// ── Link a finished Sale Entry sale back to its originating order
//    (traceability only — called by sale/entry.php after saveSale()
//    succeeds in an ?online_order=<id> context). Does not re-check
//    approval role since any logged-in staff member can complete a
//    sale that was already approved.
function api_link_sale(array $b): void {
    $id     = (int) ($b['id'] ?? 0);
    $saleId = (int) ($b['sale_id'] ?? 0);
    if (!$id || !$saleId) fail('Missing id or sale_id');

    $order = db_row("SELECT id, order_no FROM online_orders WHERE id = ?", [$id]);
    if (!$order) fail('Order not found.');

    db_run("UPDATE online_orders SET converted_sale_id = ? WHERE id = ?", [$saleId, $id]);

    log_action('update', 'online_orders', $id,
        "Linked {$order['order_no']} to Sale #$saleId");

    ok(['msg' => 'Linked.']);
}

// ── Reject ────────────────────────────────────────────────────
function api_reject(array $b): void {
    if (!can_approve_online_order()) fail('Access denied. Admin or Manager role required.');

    $id     = (int) ($b['id'] ?? 0);
    $reason = trim($b['reason'] ?? '');
    if (!$id) fail('Missing id');
    if (!$reason) fail('A rejection reason is required.');

    $order = db_row("SELECT * FROM online_orders WHERE id = ?", [$id]);
    if (!$order) fail('Order not found.');
    if ($order['status'] !== 'pending') fail('This order has already been reviewed.');

    db_run(
        "UPDATE online_orders
            SET status = 'rejected', rejection_reason = ?, reviewed_by = ?, reviewed_at = NOW()
          WHERE id = ?",
        [$reason, current_user_id(), $id]
    );

    log_action('update', 'online_orders', $id, "Rejected {$order['order_no']} — {$reason}");

    // Notify the customer — best-effort, never blocks rejection.
    $customer = db_row("SELECT phone, email FROM customers WHERE id = ?", [$order['customer_id']]);
    if ($customer) {
        notify_order_status($customer['phone'], $customer['email'] ?: null, $order['order_no'], 'rejected', $reason);
    }

    ok(['msg' => 'Order rejected.']);
}

// ── Response helpers ──────────────────────────────────────────
function ok(array $extra = []): void {
    echo json_encode(['success' => true] + $extra);
}
function fail(string $msg): never {
    echo json_encode(['success' => false, 'error' => $msg]);
    exit;
}
