<?php
/**
 * api.php - অর্ডার, স্ট্যাটাস, ব্যালেন্স, Key সেভ (AJAX/ফর্ম থেকে কল)
 */
require_once __DIR__ . '/helpers.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/encryption.php';
require_once __DIR__ . '/steadfast.php';
require_once __DIR__ . '/consignment_helpers.php';

header('Content-Type: application/json; charset=utf-8');

function validateOrderPayload($data) {
    if (empty($data['invoice']) || empty($data['recipient_name']) || empty($data['recipient_phone']) || empty($data['recipient_address'])) {
        return 'ইনভয়েস, নাম, ফোন, ঠিকানা অবশ্যক।';
    }
    if (!preg_match('/^01[0-9]{9}$/', (string) $data['recipient_phone'])) {
        return 'প্রাপকের ফোন ১১ সংখ্যার সঠিক বাংলাদেশি মোবাইল নম্বর দিন (যেমন 01712345678)।';
    }
    if (!in_array((int) $data['delivery_type'], [0, 1], true)) {
        return 'ডেলিভারি টাইপ সঠিক নয়।';
    }
    if (!is_numeric($data['cod_amount']) || (float) $data['cod_amount'] < 0) {
        return 'COD Amount সঠিক নয়।';
    }
    $alt = trim((string) ($data['alternative_phone'] ?? ''));
    if ($alt !== '' && !preg_match('/^01[0-9]{9}$/', $alt)) {
        return 'বিকল্প ফোন ১১ অঙ্কের সঠিক মোবাইল নম্বর দিন বা খালি রাখুন।';
    }
    $em = trim((string) ($data['recipient_email'] ?? ''));
    if ($em !== '' && !filter_var($em, FILTER_VALIDATE_EMAIL)) {
        return 'ইমেইল ফরম্যাট সঠিক নয়।';
    }
    $lot = $data['total_lot'] ?? null;
    if ($lot !== null && $lot !== '' && (!is_numeric($lot) || (float) $lot < 0)) {
        return 'Total lot সংখ্যা সঠিক নয়।';
    }
    return null;
}

function ensureOrderAttemptLogTable($pdo) {
    static $ready = false;
    if ($ready) return;
    $pdo->exec("CREATE TABLE IF NOT EXISTS order_attempt_logs (
        id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        user_id INT NOT NULL,
        invoice VARCHAR(128) NOT NULL,
        request_hash VARCHAR(64) NOT NULL,
        http_code INT DEFAULT 0,
        success TINYINT(1) DEFAULT 0,
        response_snippet TEXT NULL,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_user_invoice (user_id, invoice),
        INDEX idx_created_at (created_at)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    $ready = true;
}

function logOrderAttempt($pdo, $userId, $invoice, $requestData, $responseData) {
    try {
        ensureOrderAttemptLogTable($pdo);
        $requestHash = hash('sha256', json_encode($requestData, JSON_UNESCAPED_UNICODE));
        $snippet = json_encode($responseData, JSON_UNESCAPED_UNICODE);
        if ($snippet !== false && strlen($snippet) > 1500) {
            $snippet = substr($snippet, 0, 1500);
        }
        $st = $pdo->prepare('INSERT INTO order_attempt_logs (user_id, invoice, request_hash, http_code, success, response_snippet) VALUES (?, ?, ?, ?, ?, ?)');
        $st->execute([
            (int) $userId,
            (string) $invoice,
            (string) $requestHash,
            (int) ($responseData['http_code'] ?? 0),
            !empty($responseData['success']) ? 1 : 0,
            $snippet
        ]);
    } catch (Throwable $e) {
        // Logging must not break order flow.
    }
}

function ensureConsignmentApiLogTable($pdo) {
    static $ready = false;
    if ($ready) {
        return;
    }
    $pdo->exec("CREATE TABLE IF NOT EXISTS consignment_api_logs (
        id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        user_id INT NOT NULL,
        action VARCHAR(64) NOT NULL,
        source VARCHAR(32) NULL,
        endpoint VARCHAR(255) NULL,
        http_code INT DEFAULT 0,
        parse_mode VARCHAR(64) NULL,
        item_count INT DEFAULT 0,
        integration_not_supported TINYINT(1) DEFAULT 0,
        snippet TEXT NULL,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_user_created (user_id, created_at)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
    $ready = true;
}

function logConsignmentApi($pdo, $userId, $action, array $meta) {
    try {
        ensureConsignmentApiLogTable($pdo);
        $snippet = json_encode($meta, JSON_UNESCAPED_UNICODE);
        if ($snippet !== false && strlen($snippet) > 1200) {
            $snippet = substr($snippet, 0, 1200);
        }
        $st = $pdo->prepare('INSERT INTO consignment_api_logs (user_id, action, source, endpoint, http_code, parse_mode, item_count, integration_not_supported, snippet) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)');
        $st->execute([
            (int) $userId,
            (string) $action,
            $meta['source'] ?? null,
            $meta['endpoint'] ?? null,
            (int) ($meta['http_code'] ?? 0),
            $meta['parse_mode'] ?? null,
            (int) ($meta['item_count'] ?? 0),
            !empty($meta['integration_not_supported']) ? 1 : 0,
            $snippet,
        ]);
    } catch (Throwable $e) {
        // non-fatal
    }
}

function parseConsignmentDateParams() {
    $from = trim($_GET['from_date'] ?? $_POST['from_date'] ?? '');
    $to = trim($_GET['to_date'] ?? $_POST['to_date'] ?? '');
    if ($from !== '' && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $from)) {
        return ['error' => 'from_date ফরম্যাট YYYY-MM-DD হতে হবে।'];
    }
    if ($to !== '' && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $to)) {
        return ['error' => 'to_date ফরম্যাট YYYY-MM-DD হতে হবে।'];
    }
    return ['from_date' => $from !== '' ? $from : null, 'to_date' => $to !== '' ? $to : null];
}

function buildConsignmentQueryForUpstream($page, $limit) {
    $q = [
        'page' => $page,
        'per_page' => $limit,
        'limit' => $limit,
    ];
    $from = trim($_GET['from_date'] ?? $_POST['from_date'] ?? '');
    $to = trim($_GET['to_date'] ?? $_POST['to_date'] ?? '');
    if ($from !== '') {
        $q['from_date'] = $from;
        $q['start_date'] = $from;
        $q['date_from'] = $from;
    }
    if ($to !== '') {
        $q['to_date'] = $to;
        $q['end_date'] = $to;
        $q['date_to'] = $to;
    }
    return $q;
}

/**
 * @return array{error?:string,friendly?:array,agg?:array,normalized?:array,dates?:array}
 */
function fetchNormalizedConsignmentsBundle($pdo, $userId, array $keys) {
    $dates = parseConsignmentDateParams();
    if (isset($dates['error'])) {
        return ['error' => $dates['error']];
    }
    session_name(SESSION_NAME);
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    $cacheSig = md5(($dates['from_date'] ?? '') . '|' . ($dates['to_date'] ?? ''));
    $ck = 'consign_bundle_' . (int) $userId;
    if (isset($_SESSION[$ck]) && is_array($_SESSION[$ck]) && ($_SESSION[$ck]['sig'] ?? '') === $cacheSig && (time() - (int) ($_SESSION[$ck]['t'] ?? 0)) < 90) {
        $cached = $_SESSION[$ck]['bundle'];
        if (is_array($cached) && isset($cached['normalized'])) {
            return $cached;
        }
    }
    $query = buildConsignmentQueryForUpstream(1, 200);
    $agg = steadfastFetchConsignmentsAggregated($keys['apiKey'], $keys['secretKey'], $query);
    if (!empty($agg['friendly'])) {
        return ['friendly' => $agg['friendly']];
    }
    $normalized = [];
    foreach ($agg['items'] as $row) {
        if (is_array($row)) {
            $normalized[] = normalizeConsignmentRow($row);
        }
    }
    $normalized = filterConsignmentsByDateRange($normalized, $dates['from_date'], $dates['to_date']);
    logConsignmentApi($pdo, $userId, 'consignment_fetch', [
        'source' => $agg['source'],
        'endpoint' => $agg['endpoint'],
        'http_code' => $agg['http_code'],
        'parse_mode' => $agg['parse_mode'],
        'item_count' => count($normalized),
        'integration_not_supported' => !empty($agg['integration_not_supported']),
        'payments_scanned' => $agg['payments_scanned'] ?? 0,
    ]);
    $out = ['agg' => $agg, 'normalized' => $normalized, 'dates' => $dates];
    $_SESSION[$ck] = ['sig' => $cacheSig, 't' => time(), 'bundle' => $out];
    return $out;
}

/** @return array<int,array> */
function parseSteadfastDataList($decoded) {
    if (!is_array($decoded)) {
        return [];
    }
    if (isset($decoded['data']) && is_array($decoded['data'])) {
        return $decoded['data'];
    }
    if ($decoded === []) {
        return [];
    }
    $keys = array_keys($decoded);
    if ($keys === range(0, count($decoded) - 1)) {
        return $decoded;
    }
    return [];
}

function aggregateReturnRequestStatuses(array $rows) {
    $allowed = ['pending', 'approved', 'processing', 'completed', 'cancelled'];
    $out = array_fill_keys($allowed, 0);
    $out['other'] = 0;
    foreach ($rows as $row) {
        if (!is_array($row)) {
            continue;
        }
        $st = strtolower(trim((string) ($row['status'] ?? '')));
        if ($st === '') {
            continue;
        }
        if (in_array($st, $allowed, true)) {
            $out[$st]++;
        } else {
            $out['other']++;
        }
    }
    return $out;
}

function summarizePaymentRowForDashboard(array $row) {
    return [
        'id' => (string) ($row['id'] ?? $row['payment_id'] ?? ''),
        'amount' => $row['amount'] ?? $row['total'] ?? null,
        'date' => $row['date'] ?? $row['created_at'] ?? $row['updated_at'] ?? null,
    ];
}

function policeStationPreviewLabel(array $row) {
    return (string) ($row['name'] ?? $row['station_name'] ?? $row['title'] ?? '');
}

$userId = getUserId();
if (!$userId) {
    echo json_encode(['success' => false, 'message' => 'লগইন প্রয়োজন।']);
    exit;
}

$action = $_POST['action'] ?? $_GET['action'] ?? '';

// Key সেভ
if ($action === 'save_keys') {
    $api_key = trim($_POST['api_key'] ?? '');
    $secret_key = trim($_POST['secret_key'] ?? '');
    if (empty($api_key) || empty($secret_key)) {
        echo json_encode(['success' => false, 'message' => 'API Key ও Secret Key দুটোই দিন।']);
        exit;
    }
    $enc_api = encryptKey($api_key);
    $enc_secret = encryptKey($secret_key);
    $st = $pdo->prepare('INSERT INTO user_keys (user_id, api_key_encrypted, secret_key_encrypted) VALUES (?, ?, ?)
                         ON DUPLICATE KEY UPDATE api_key_encrypted = VALUES(api_key_encrypted), secret_key_encrypted = VALUES(secret_key_encrypted), updated_at = NOW()');
    $st->execute([$userId, $enc_api, $enc_secret]);
    echo json_encode(['success' => true, 'message' => 'Steadfast Key সেভ হয়েছে।']);
    exit;
}

// Key আছে কিনা চেক
if ($action === 'check_keys') {
    $keys = getUserKeys($userId);
    echo json_encode(['success' => true, 'hasKeys' => $keys !== null]);
    exit;
}

$keys = getUserKeys($userId);
if (!$keys) {
    echo json_encode(['success' => false, 'message' => 'প্রথমে সেটিংস থেকে Steadfast API Key ও Secret Key সেভ করুন।']);
    exit;
}

// একক অর্ডার
if ($action === 'create_order') {
    $lotRaw = trim((string) ($_POST['total_lot'] ?? ''));
    $data = [
        'invoice' => trim($_POST['invoice'] ?? ''),
        'recipient_name' => trim($_POST['recipient_name'] ?? ''),
        'recipient_phone' => trim($_POST['recipient_phone'] ?? ''),
        'recipient_address' => trim($_POST['recipient_address'] ?? ''),
        'cod_amount' => (float) ($_POST['cod_amount'] ?? 0),
        'note' => trim($_POST['note'] ?? '') ?: null,
        'delivery_type' => (int) ($_POST['delivery_type'] ?? 0),
        'alternative_phone' => trim($_POST['alternative_phone'] ?? ''),
        'recipient_email' => trim($_POST['recipient_email'] ?? ''),
        'item_description' => trim($_POST['item_description'] ?? ''),
        'total_lot' => $lotRaw === '' ? null : $lotRaw,
    ];
    $validationError = validateOrderPayload($data);
    if ($validationError !== null) {
        echo json_encode(['success' => false, 'message' => $validationError]);
        exit;
    }
    $payload = [
        'invoice' => $data['invoice'],
        'recipient_name' => $data['recipient_name'],
        'recipient_phone' => $data['recipient_phone'],
        'recipient_address' => $data['recipient_address'],
        'cod_amount' => $data['cod_amount'],
        'note' => $data['note'],
        'delivery_type' => $data['delivery_type'],
    ];
    if ($data['alternative_phone'] !== '') {
        $payload['alternative_phone'] = $data['alternative_phone'];
    }
    if ($data['recipient_email'] !== '') {
        $payload['recipient_email'] = $data['recipient_email'];
    }
    if ($data['item_description'] !== '') {
        $payload['item_description'] = $data['item_description'];
    }
    if ($data['total_lot'] !== null && $data['total_lot'] !== '') {
        $payload['total_lot'] = (float) $data['total_lot'];
    }
    $result = steadfastCreateOrder($keys['apiKey'], $keys['secretKey'], $payload);
    $normalized = normalizeCreateOrderResult($result);
    logOrderAttempt($pdo, $userId, $payload['invoice'], $payload, $normalized);
    echo json_encode($normalized);
    exit;
}

// স্ট্যাটাস
if ($action === 'status') {
    $type = $_GET['type'] ?? $_POST['type'] ?? 'tracking';
    $value = trim($_GET['value'] ?? $_POST['value'] ?? '');
    if (empty($value)) {
        echo json_encode(['success' => false, 'message' => 'ট্র্যাকিং কোড / ইনভয়েস / কনসাইনমেন্ট ID দিন।']);
        exit;
    }
    if ($type === 'cid') {
        $result = steadfastStatusByCid($keys['apiKey'], $keys['secretKey'], $value);
    } elseif ($type === 'invoice') {
        $result = steadfastStatusByInvoice($keys['apiKey'], $keys['secretKey'], $value);
    } else {
        $result = steadfastStatusByTracking($keys['apiKey'], $keys['secretKey'], $value);
    }
    $friendly = steadfastFriendlyMessage($result);
    echo json_encode($friendly !== null ? $friendly : $result);
    exit;
}

// ব্যালেন্স
if ($action === 'balance') {
    $result = steadfastGetBalance($keys['apiKey'], $keys['secretKey']);
    $friendly = steadfastFriendlyMessage($result);
    echo json_encode($friendly !== null ? $friendly : $result);
    exit;
}

// পেমেন্ট লিস্ট
if ($action === 'payments') {
    $result = steadfastGetPayments($keys['apiKey'], $keys['secretKey']);
    $friendly = steadfastFriendlyMessage($result);
    echo json_encode($friendly !== null ? $friendly : $result);
    exit;
}

// এক পেমেন্ট (কনসাইনমেন্টসহ)
if ($action === 'payment') {
    $id = trim($_GET['id'] ?? $_POST['id'] ?? '');
    if (empty($id)) {
        echo json_encode(['success' => false, 'message' => 'পেমেন্ট ID দিন।']);
        exit;
    }
    $result = steadfastGetPaymentById($keys['apiKey'], $keys['secretKey'], $id);
    $friendly = steadfastFriendlyMessage($result);
    echo json_encode($friendly !== null ? $friendly : $result);
    exit;
}

// রিটার্ন রিকোয়েস্ট লিস্ট
if ($action === 'return_requests') {
    $result = steadfastGetReturnRequests($keys['apiKey'], $keys['secretKey']);
    $friendly = steadfastFriendlyMessage($result);
    echo json_encode($friendly !== null ? $friendly : $result);
    exit;
}

// এক রিটার্ন রিকোয়েস্ট
if ($action === 'return_request') {
    $id = trim($_GET['id'] ?? $_POST['id'] ?? '');
    if (empty($id)) {
        echo json_encode(['success' => false, 'message' => 'রিটার্ন ID দিন।']);
        exit;
    }
    $result = steadfastGetReturnRequest($keys['apiKey'], $keys['secretKey'], $id);
    $friendly = steadfastFriendlyMessage($result);
    echo json_encode($friendly !== null ? $friendly : $result);
    exit;
}

// রিটার্ন রিকোয়েস্ট তৈরি
if ($action === 'create_return') {
    $consignment_id = trim($_POST['consignment_id'] ?? $_POST['invoice'] ?? $_POST['tracking_code'] ?? '');
    $reason = trim($_POST['reason'] ?? '');
    if (empty($consignment_id)) {
        echo json_encode(['success' => false, 'message' => 'কনসাইনমেন্ট ID / ইনভয়েস / ট্র্যাকিং কোড দিন।']);
        exit;
    }
    $data = ['consignment_id' => $consignment_id];
    if ($reason !== '') $data['reason'] = $reason;
    $result = steadfastCreateReturn($keys['apiKey'], $keys['secretKey'], $data);
    $friendly = steadfastFriendlyMessage($result);
    echo json_encode($friendly !== null ? $friendly : $result);
    exit;
}

// পুলিশ স্টেশন লিস্ট
if ($action === 'police_stations') {
    $result = steadfastGetPoliceStations($keys['apiKey'], $keys['secretKey']);
    $friendly = steadfastFriendlyMessage($result);
    echo json_encode($friendly !== null ? $friendly : $result);
    exit;
}

// ড্যাশবোর্ড একসাথে: ব্যালেন্স, রিটার্ন, পেমেন্ট, পুলিশ, কনসাইনমেন্ট সারাংশ
if ($action === 'dashboard_snapshot') {
    $partialErrors = [];
    $balance = null;
    $returnsBlock = ['total' => 0, 'by_status' => array_fill_keys(['pending', 'approved', 'processing', 'completed', 'cancelled', 'other'], 0)];
    $paymentsBlock = ['total' => 0, 'recent' => []];
    $policeBlock = ['count' => 0, 'preview' => []];
    $consignmentTotals = null;
    $officialDeliveryCounts = null;
    $consignmentMeta = null;

    $balRes = steadfastGetBalance($keys['apiKey'], $keys['secretKey']);
    $balFriendly = steadfastFriendlyMessage($balRes);
    if ($balFriendly !== null) {
        echo json_encode($balFriendly);
        exit;
    }
    if (isset($balRes['current_balance'])) {
        $balance = $balRes['current_balance'];
    } else {
        $partialErrors[] = 'balance: ' . (string) ($balRes['error'] ?? $balRes['message'] ?? 'no data');
    }

    $retRes = steadfastGetReturnRequests($keys['apiKey'], $keys['secretKey']);
    if (steadfastFriendlyMessage($retRes) !== null) {
        $partialErrors[] = 'returns: ' . (steadfastFriendlyMessage($retRes)['message'] ?? 'error');
    } else {
        $retList = parseSteadfastDataList($retRes);
        $returnsBlock['total'] = count($retList);
        $returnsBlock['by_status'] = aggregateReturnRequestStatuses($retList);
    }

    $payRes = steadfastGetPayments($keys['apiKey'], $keys['secretKey']);
    if (steadfastFriendlyMessage($payRes) !== null) {
        $partialErrors[] = 'payments: ' . (steadfastFriendlyMessage($payRes)['message'] ?? 'error');
    } else {
        $payList = parseSteadfastDataList($payRes);
        $paymentsBlock['total'] = count($payList);
        $slice = array_slice($payList, 0, 8);
        foreach ($slice as $pr) {
            if (is_array($pr)) {
                $paymentsBlock['recent'][] = summarizePaymentRowForDashboard($pr);
            }
        }
    }

    $polRes = steadfastGetPoliceStations($keys['apiKey'], $keys['secretKey']);
    if (steadfastFriendlyMessage($polRes) !== null) {
        $partialErrors[] = 'police_stations: ' . (steadfastFriendlyMessage($polRes)['message'] ?? 'error');
    } else {
        $polList = parseSteadfastDataList($polRes);
        $policeBlock['count'] = count($polList);
        for ($i = 0; $i < min(3, count($polList)); $i++) {
            if (is_array($polList[$i])) {
                $lbl = policeStationPreviewLabel($polList[$i]);
                if ($lbl !== '') {
                    $policeBlock['preview'][] = $lbl;
                }
            }
        }
    }

    $bundle = fetchNormalizedConsignmentsBundle($pdo, $userId, $keys);
    if (isset($bundle['friendly'])) {
        $partialErrors[] = 'consignments: ' . ($bundle['friendly']['message'] ?? 'error');
        $consignmentTotals = buildConsignmentTotals([]);
        $officialDeliveryCounts = buildOfficialDeliveryStatusCounts([]);
        $consignmentMeta = ['item_count' => 0, 'integration_not_supported' => false, 'hint' => null, 'source' => null];
    } elseif (isset($bundle['error'])) {
        $partialErrors[] = 'consignments: ' . $bundle['error'];
        $consignmentTotals = buildConsignmentTotals([]);
        $officialDeliveryCounts = buildOfficialDeliveryStatusCounts([]);
        $consignmentMeta = ['item_count' => 0, 'integration_not_supported' => false, 'hint' => null, 'source' => null];
    } else {
        $agg = $bundle['agg'];
        $normalized = $bundle['normalized'];
        $consignmentTotals = buildConsignmentTotals($normalized);
        $officialDeliveryCounts = buildOfficialDeliveryStatusCounts($normalized);
        $consignmentMeta = [
            'source' => $agg['source'],
            'endpoint' => $agg['endpoint'],
            'parse_mode' => $agg['parse_mode'],
            'http_code' => $agg['http_code'],
            'integration_not_supported' => !empty($agg['integration_not_supported']),
            'hint' => $agg['message'],
            'payments_scanned' => $agg['payments_scanned'] ?? 0,
            'item_count' => count($normalized),
        ];
    }

    echo json_encode([
        'success' => true,
        'balance' => $balance,
        'returns' => $returnsBlock,
        'payments' => $paymentsBlock,
        'police' => $policeBlock,
        'consignment_totals' => $consignmentTotals,
        'official_delivery_counts' => $officialDeliveryCounts,
        'consignment_meta' => $consignmentMeta,
        'meta' => [
            'partial_errors' => $partialErrors,
            'delivery_status_note' => 'Counts match Steadfast official delivery_status where raw parcel status is present (partial data if list comes from payments only).',
        ],
    ]);
    exit;
}

// কনসাইনমেন্ট স্ট্যাটাস ক্যাটাগরি সারাংশ (তারিখ ফিল্টার অপশনাল)
if ($action === 'consignment_summary') {
    $bundle = fetchNormalizedConsignmentsBundle($pdo, $userId, $keys);
    if (isset($bundle['error'])) {
        echo json_encode(['success' => false, 'message' => $bundle['error']]);
        exit;
    }
    if (isset($bundle['friendly'])) {
        echo json_encode($bundle['friendly']);
        exit;
    }
    $agg = $bundle['agg'];
    $normalized = $bundle['normalized'];
    $totals = buildConsignmentTotals($normalized);
    echo json_encode([
        'success' => true,
        'totals' => $totals,
        'meta' => [
            'source' => $agg['source'],
            'endpoint' => $agg['endpoint'],
            'parse_mode' => $agg['parse_mode'],
            'http_code' => $agg['http_code'],
            'integration_not_supported' => !empty($agg['integration_not_supported']),
            'hint' => $agg['message'],
            'payments_scanned' => $agg['payments_scanned'] ?? 0,
            'item_count' => count($normalized),
        ],
    ]);
    exit;
}

// কনসাইনমেন্ট লিস্ট (ক্যাটাগরি + পেজিনেশন)
if ($action === 'consignment_list') {
    $bundle = fetchNormalizedConsignmentsBundle($pdo, $userId, $keys);
    if (isset($bundle['error'])) {
        echo json_encode(['success' => false, 'message' => $bundle['error']]);
        exit;
    }
    if (isset($bundle['friendly'])) {
        echo json_encode($bundle['friendly']);
        exit;
    }
    $agg = $bundle['agg'];
    $normalized = $bundle['normalized'];
    $totals = buildConsignmentTotals($normalized);
    $bucket = validateConsignmentBucket($_GET['status'] ?? $_POST['status'] ?? 'all');
    $page = max(1, (int) ($_GET['page'] ?? $_POST['page'] ?? 1));
    $limit = max(1, min(100, (int) ($_GET['limit'] ?? $_POST['limit'] ?? 25)));
    $filtered = filterConsignmentsByBucket($normalized, $bucket);
    $pageData = paginateArray($filtered, $page, $limit);
    echo json_encode([
        'success' => true,
        'totals' => $totals,
        'status' => $bucket,
        'data' => $pageData['data'],
        'pagination' => $pageData['pagination'],
        'meta' => [
            'source' => $agg['source'],
            'endpoint' => $agg['endpoint'],
            'parse_mode' => $agg['parse_mode'],
            'http_code' => $agg['http_code'],
            'integration_not_supported' => !empty($agg['integration_not_supported']),
            'hint' => $agg['message'],
            'payments_scanned' => $agg['payments_scanned'] ?? 0,
            'item_count' => count($normalized),
        ],
    ]);
    exit;
}

echo json_encode(['success' => false, 'message' => 'অজানা অ্যাকশন।']);
?>
