<?php
/**
 * Parse JSON body fields and POST /create_order to Packzy/Steadfast.
 * Used by steadfast-create-order-proxy.php and kuriyar-api.php.
 */

/**
 * @return array{forward: array}|array{error: array{message: string, http: int}}
 */
function steadfast_parse_create_order_body(array $body) {
    $invoice = isset($body['invoice']) ? trim((string) $body['invoice']) : '';
    $recipientName = isset($body['recipient_name']) ? trim((string) $body['recipient_name']) : '';
    $recipientPhone = isset($body['recipient_phone']) ? preg_replace('/\D/', '', (string) $body['recipient_phone']) : '';
    $recipientAddress = isset($body['recipient_address']) ? trim((string) $body['recipient_address']) : '';
    $codAmount = isset($body['cod_amount']) ? $body['cod_amount'] : null;

    if ($invoice === '' || !preg_match('/^[a-zA-Z0-9_-]{1,191}$/', $invoice)) {
        return ['error' => ['message' => 'invoice is required and must be alphanumeric with hyphens/underscores only (max 191 chars).', 'http' => 400]];
    }
    if ($recipientName === '' || mb_strlen($recipientName, 'UTF-8') > 100) {
        return ['error' => ['message' => 'recipient_name is required and must be at most 100 characters.', 'http' => 400]];
    }
    if (strlen($recipientPhone) !== 11 || !preg_match('/^0[1-9]\d{9}$/', $recipientPhone)) {
        return ['error' => ['message' => 'recipient_phone must be a valid 11-digit Bangladesh mobile number.', 'http' => 400]];
    }
    if ($recipientAddress === '' || mb_strlen($recipientAddress, 'UTF-8') > 250) {
        return ['error' => ['message' => 'recipient_address is required and must be at most 250 characters.', 'http' => 400]];
    }
    if ($codAmount === null || !is_numeric($codAmount) || (float) $codAmount < 0) {
        return ['error' => ['message' => 'cod_amount is required and must be a number >= 0.', 'http' => 400]];
    }

    $forward = [
        'invoice' => $invoice,
        'recipient_name' => $recipientName,
        'recipient_phone' => $recipientPhone,
        'recipient_address' => $recipientAddress,
        'cod_amount' => (float) $codAmount,
    ];

    $optionalString = function ($key, $maxLen) use ($body, &$forward) {
        if (!isset($body[$key]) || $body[$key] === '' || $body[$key] === null) {
            return;
        }
        $v = trim((string) $body[$key]);
        if ($v !== '' && mb_strlen($v, 'UTF-8') <= $maxLen) {
            $forward[$key] = $v;
        }
    };

    $optionalString('note', 2000);
    $optionalString('item_description', 2000);
    $optionalString('recipient_email', 190);

    if (isset($body['alternative_phone']) && $body['alternative_phone'] !== '') {
        $alt = preg_replace('/\D/', '', (string) $body['alternative_phone']);
        if (strlen($alt) === 11 && preg_match('/^0[1-9]\d{9}$/', $alt)) {
            $forward['alternative_phone'] = $alt;
        }
    }

    if (isset($body['total_lot']) && is_numeric($body['total_lot']) && (float) $body['total_lot'] >= 0) {
        $forward['total_lot'] = (float) $body['total_lot'];
    }

    if (isset($body['delivery_type']) && ($body['delivery_type'] === 0 || $body['delivery_type'] === 1 || $body['delivery_type'] === '0' || $body['delivery_type'] === '1')) {
        $forward['delivery_type'] = (int) $body['delivery_type'];
    }

    return ['forward' => $forward];
}

/**
 * @return array{http: int, raw: string, data: ?array}
 */
function steadfast_create_order_http_post($apiKey, $secretKey, $baseUrl, array $forward) {
    $url = rtrim((string) $baseUrl, '/') . '/create_order';
    $payload = json_encode($forward, JSON_UNESCAPED_UNICODE);

    if (function_exists('curl_init')) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $payload,
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Api-Key: ' . $apiKey,
                'Secret-Key: ' . $secretKey,
            ],
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 45,
        ]);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($errno !== 0 || $response === false) {
            return ['http' => 502, 'raw' => '', 'data' => null];
        }
        $data = json_decode((string) $response, true);
        return ['http' => $httpCode, 'raw' => (string) $response, 'data' => is_array($data) ? $data : null];
    }

    $ctx = stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => "Content-Type: application/json\r\nApi-Key: {$apiKey}\r\nSecret-Key: {$secretKey}\r\n",
            'content' => $payload,
            'timeout' => 45,
            'ignore_errors' => true,
        ],
        'ssl' => [
            'verify_peer' => true,
            'verify_peer_name' => true,
        ],
    ]);

    $response = @file_get_contents($url, false, $ctx);
    if ($response === false) {
        return ['http' => 502, 'raw' => '', 'data' => null];
    }
    $httpCode = 200;
    if (!empty($http_response_header)) {
        foreach ($http_response_header as $h) {
            if (preg_match('/^HTTP\/\S+\s+(\d+)/', $h, $m)) {
                $httpCode = (int) $m[1];
                break;
            }
        }
    }
    $data = json_decode((string) $response, true);
    return ['http' => $httpCode, 'raw' => (string) $response, 'data' => is_array($data) ? $data : null];
}

/**
 * Whether Packzy response indicates a created consignment with tracking (matches core normalizeCreateOrderResult intent).
 */
function steadfast_packzy_create_succeeded(?array $data) {
    if (!is_array($data)) {
        return false;
    }
    $consignment = isset($data['consignment']) && is_array($data['consignment']) ? $data['consignment'] : null;
    if ($consignment === null) {
        return false;
    }
    $hasTracking = !empty($consignment['tracking_code']);
    $ok = !empty($data['ok']);
    $statusOk = isset($data['status']) && (int) $data['status'] === 200;
    return $hasTracking && ($ok || $statusOk);
}
