<?php

declare(strict_types=1);

// Run with: API_BASE_URL=https://demoapi.quick-assess.com API_BEARER_TOKEN=... php php_client.php
$baseUrl = rtrim((string) getenv('API_BASE_URL'), '/');
$bearerToken = (string) getenv('API_BEARER_TOKEN');

if ($baseUrl === '' || $bearerToken === '') {
    throw new RuntimeException('Set API_BASE_URL and API_BEARER_TOKEN in the environment.');
}

/** @return array{status: int, headers: array<string, string>, body: array<string, mixed>} */
function apiRequest(string $baseUrl, string $bearerToken, string $method, string $path, ?array $payload = null, ?string $idempotencyKey = null): array
{
    $headers = [
        'Accept: application/json',
        'Authorization: Bearer '.$bearerToken,
        'X-Request-ID: php-example-'.bin2hex(random_bytes(6)),
    ];
    if ($payload !== null) {
        $headers[] = 'Content-Type: application/json';
    }
    if ($idempotencyKey !== null) {
        $headers[] = 'Idempotency-Key: '.$idempotencyKey;
    }

    $handle = curl_init($baseUrl.$path);
    curl_setopt_array($handle, [
        CURLOPT_CUSTOMREQUEST => $method,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POSTFIELDS => $payload === null ? null : json_encode($payload, JSON_THROW_ON_ERROR),
        CURLOPT_TIMEOUT => 30,
    ]);
    $rawBody = curl_exec($handle);
    if ($rawBody === false) {
        throw new RuntimeException(curl_error($handle));
    }
    $status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
    curl_close($handle);
    $body = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
    if ($status >= 400) {
        throw new RuntimeException(sprintf('API %d %s: %s', $status, $body['error']['code'] ?? 'unknown', $body['error']['message'] ?? 'request failed'));
    }

    return ['status' => $status, 'headers' => [], 'body' => $body];
}

function downloadOfficialPdf(string $baseUrl, string $bearerToken, string $requestReference, string $destination): void
{
    $handle = curl_init($baseUrl.'/api/v2/assessments/'.rawurlencode($requestReference).'/report.pdf');
    $headers = ['Accept: application/pdf', 'Authorization: Bearer '.$bearerToken];
    $responseHeaders = [];
    curl_setopt_array($handle, [
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_HEADERFUNCTION => static function ($curl, string $header) use (&$responseHeaders): int {
            if (str_contains($header, ':')) {
                [$name, $value] = explode(':', $header, 2);
                $responseHeaders[mb_strtolower(trim($name))] = trim($value);
            }

            return strlen($header);
        },
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 60,
    ]);
    $pdf = curl_exec($handle);
    $status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
    $contentType = mb_strtolower((string) ($responseHeaders['content-type'] ?? ''));
    if ($pdf === false || $status >= 400 || ! str_starts_with($contentType, 'application/pdf') || ! str_starts_with($pdf, '%PDF-')) {
        curl_close($handle);
        throw new RuntimeException("PDF download failed or returned a non-PDF response with HTTP {$status}.");
    }
    curl_close($handle);
    if (file_put_contents($destination, $pdf, LOCK_EX) === false) {
        throw new RuntimeException("PDF could not be saved to {$destination}.");
    }
    echo 'Saved official PDF version '.($responseHeaders['x-assessment-report-version'] ?? 'unknown')." to {$destination}\n";
}

// 1. Verify the token-owner, insurer binding, abilities, and mapped permissions.
$context = apiRequest($baseUrl, $bearerToken, 'GET', '/api/v2/integration/context');
print_r($context['body']['data']);

// 2. Register a vehicle. Reuse the same key if the network response is uncertain.
$vehicleRegistration = apiRequest($baseUrl, $bearerToken, 'POST', '/api/v2/vehicles', [
    'external_vehicle_reference' => 'PHP-SYNTHETIC-VEHICLE-001',
    'make' => 'MERCEDES BENZ',
    'model' => 'C CLASS- W202',
    'manufacture_year' => 2001,
    'variant' => null,
    'registration_number' => 'UAA 123X',
    'chassis_number' => 'SYNTHETIC-CHASSIS-001',
], 'php-vehicle-'.bin2hex(random_bytes(12)));
$vehicleReference = (string) $vehicleRegistration['body']['data']['vehicle']['vehicle_reference'];
echo "Vehicle: {$vehicleReference}\n";

// 3. Retrieve the safe vehicle projection.
$vehicle = apiRequest($baseUrl, $bearerToken, 'GET', '/api/v2/vehicles/'.rawurlencode($vehicleReference));
print_r($vehicle['body']['data']['vehicle']);

// 4. Submit an assessment using the registered vehicle reference.
$assessmentSubmission = apiRequest($baseUrl, $bearerToken, 'POST', '/api/v2/assessments', [
    'external_client_reference' => 'PHP-SYNTHETIC-CLAIM-001',
    'currency' => 'UGX',
    'vehicle_reference' => $vehicleReference,
    'parts' => [
        ['part_name' => 'Front Bumper', 'quantity' => 1, 'claimed_amount' => 450000],
    ],
], 'php-assessment-'.bin2hex(random_bytes(12)));
$requestReference = (string) $assessmentSubmission['body']['data']['request_reference'];
echo "Request: {$requestReference}\n";

// 5. Poll, then retrieve the safe JSON result. A pending_catalogue result is expected until pricing is configured.
for ($attempt = 0; $attempt < 12; $attempt++) {
    $status = apiRequest($baseUrl, $bearerToken, 'GET', '/api/v2/assessments/'.rawurlencode($requestReference).'/status');
    $statusData = $status['body']['data'];
    echo 'Processing status: '.($statusData['status'] ?? 'unknown')."\n";
    if (in_array($statusData['status'] ?? null, ['completed', 'pending_catalogue', 'failed'], true)) {
        break;
    }
    sleep((int) ($statusData['poll_after_seconds'] ?? 5));
}
$result = apiRequest($baseUrl, $bearerToken, 'GET', '/api/v2/assessments/'.rawurlencode($requestReference));
print_r($result['body']['data']);

// 6. After an authorized workflow user finalizes the assessment, call:
// downloadOfficialPdf($baseUrl, $bearerToken, $requestReference, __DIR__.'/official-assessment-synthetic.pdf');
// The bearer token must have assessments:reports:read. Save outside the public web root.
