<?php
/** ZYREX SHOP API client. PHP 8+, ext-curl. No automatic purchase retries. */
final class ZyrexAPI {
    private string $baseUrl;
    private string $apiKey;
    public function __construct(?string $baseUrl = null, ?string $apiKey = null) {
        $this->baseUrl = rtrim($baseUrl ?? (getenv('ZYREX_API_URL') ?: ''), '/');
        $this->apiKey = $apiKey ?? (getenv('ZYREX_API_KEY') ?: '');
        if (!preg_match('#^https?://#', $this->baseUrl) || $this->apiKey === '') {
            throw new RuntimeException('Isi ZYREX_API_URL (hingga /api/v1) dan ZYREX_API_KEY di backend.');
        }
    }
    public function request(string $method, string $path, ?array $payload = null, ?string $idempotencyKey = null): array {
        if (!str_starts_with($path, '/') || str_starts_with($path, '//') || str_contains($path, '://')) {
            throw new InvalidArgumentException('Gunakan path relatif seperti /balance.');
        }
        $method = strtoupper($method);
        $headers = ['Authorization: Bearer ' . $this->apiKey, 'Accept: application/json'];
        if ($method === 'POST' && in_array($path, ['/order', '/smm/order'], true)) {
            if ($idempotencyKey === null || strlen($idempotencyKey) < 16 || strlen($idempotencyKey) > 128) {
                throw new InvalidArgumentException('Simpan Idempotency-Key 16–128 karakter untuk satu order dan retry-nya.');
            }
            $headers[] = 'Idempotency-Key: ' . $idempotencyKey;
        }
        $handle = curl_init($this->baseUrl . $path);
        $options = [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method,
                    CURLOPT_HTTPHEADER => $headers, CURLOPT_CONNECTTIMEOUT => 5,
                    CURLOPT_TIMEOUT => 25, CURLOPT_FOLLOWLOCATION => false];
        if ($payload !== null) {
            $headers[] = 'Content-Type: application/json';
            $options[CURLOPT_HTTPHEADER] = $headers;
            $options[CURLOPT_POSTFIELDS] = json_encode($payload, JSON_THROW_ON_ERROR);
        }
        curl_setopt_array($handle, $options);
        $raw = curl_exec($handle);
        $status = curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
        curl_close($handle);
        if ($raw === false) {
            throw new RuntimeException('Koneksi gagal/timeout. Hasil POST mungkin belum pasti; jangan ulang dengan key berbeda.');
        }
        $body = json_decode($raw, true);
        if (!is_array($body)) $body = ['success' => false, 'message' => 'Respons bukan JSON; periksa status HTTP.'];
        return ['http_status' => $status, 'body' => $body];
    }
}
if (PHP_SAPI === 'cli' && realpath($_SERVER['SCRIPT_FILENAME']) === __FILE__) {
    try {
        $method = $argv[1] ?? 'GET'; $path = $argv[2] ?? '/balance';
        $payload = isset($argv[3]) ? json_decode(file_get_contents($argv[3]), true, 512, JSON_THROW_ON_ERROR) : null;
        if ($payload !== null && !is_array($payload)) throw new InvalidArgumentException('Payload harus objek JSON.');
        echo json_encode((new ZyrexAPI())->request($method, $path, $payload, $argv[4] ?? null), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
    } catch (Throwable $error) { fwrite(STDERR, $error->getMessage() . PHP_EOL); exit(1); }
}
