<?php
declare(strict_types=1);
// Noryk Gateway: execute em PHP 8.3+ no backend, com a extensão cURL.
// A credencial deve vir do ambiente protegido; nunca do código enviado ao navegador.
$apiKey = getenv('NORYK_API_KEY');
$operationKey = getenv('IDEMPOTENCY_KEY');
$base = rtrim(getenv('NORYK_BASE_URL') ?: 'https://gateway.noryk.finance', '/');
$parts = parse_url($base);
if (!$apiKey || !$operationKey) {
    throw new RuntimeException('Configure NORYK_API_KEY e a IDEMPOTENCY_KEY já persistida para este pedido.');
}
if (preg_match('/[\x00-\x20\x7f]/', $apiKey)) {
    throw new RuntimeException('A credencial não pode conter espaços ou caracteres de controle.');
}
if (!preg_match('/^[a-zA-Z0-9_.:-]{8,128}$/D', $operationKey)) {
    throw new RuntimeException('IDEMPOTENCY_KEY deve ter de 8 a 128 caracteres permitidos.');
}
if ($parts === false || isset($parts['user']) || isset($parts['pass']) || isset($parts['query']) || isset($parts['fragment']) || !empty($parts['path'])) {
    throw new RuntimeException('NORYK_BASE_URL deve conter apenas a origem da API.');
}
$scheme = $parts['scheme'] ?? '';
$hostname = $parts['host'] ?? '';
if ($scheme !== 'https' && !($scheme === 'http' && in_array($hostname, ['localhost', '127.0.0.1', '[::1]'], true))) {
    throw new RuntimeException('Use HTTPS; HTTP é permitido somente no desenvolvimento local.');
}

$curl = curl_init($base . '/v1/charges');
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 15,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
        'Idempotency-Key: ' . $operationKey,
    ],
    CURLOPT_POSTFIELDS => json_encode(['amountCents' => 10000, 'description' => 'Pedido 000001'], JSON_THROW_ON_ERROR),
]);
$raw = curl_exec($curl);
$status = (int) curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
curl_close($curl);
if ($raw === false) {
    throw new RuntimeException('Resultado sem confirmação. Preserve o mesmo corpo e a chave persistida; consulte a operação antes de tentar novamente.');
}
try {
    $result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException) {
    throw new RuntimeException('Resposta sem confirmação válida. Preserve a chave e consulte o mesmo pedido.');
}
if ($status < 200 || $status >= 300) {
    // Registre código e requestId; não registre o bearer nem os dados de pagadores.
    $detail = is_array($result) && is_array($result['error'] ?? null) ? $result['error'] : [];
    throw new RuntimeException('HTTP ' . $status . ' / ' . ($detail['code'] ?? 'HTTP_ERROR') . ' / requestId: ' . ($detail['requestId'] ?? 'indisponivel'));
}
if (!is_array($result) || !is_string($result['id'] ?? null) || trim($result['id']) === '' || !is_string($result['status'] ?? null) || $result['status'] === '' || ($result['amountCents'] ?? null) !== 10000) {
    throw new RuntimeException('Resposta sem confirmação válida. Preserve a chave e consulte o mesmo pedido.');
}
// Persista $result['id'] junto da chave do pedido no seu banco.
// $result['qrCode'] contém o Pix copia e cola, pagável no ambiente real.
echo json_encode(array_intersect_key($result, array_flip(['id', 'status', 'amountCents', 'feeCents', 'netCents'])), JSON_THROW_ON_ERROR) . PHP_EOL;
